1 // Copyright (c) 2012 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.
9 #include "base/command_line.h"
10 #include "base/logging.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "chrome/browser/chrome_notification_types.h"
13 #include "chrome/browser/net/url_request_mock_util.h"
14 #include "chrome/browser/ui/browser.h"
15 #include "chrome/browser/ui/browser_commands.h"
16 #include "chrome/browser/ui/browser_list.h"
17 #include "chrome/browser/ui/tabs/tab_strip_model.h"
18 #include "chrome/common/chrome_switches.h"
19 #include "chrome/test/base/in_process_browser_test.h"
20 #include "chrome/test/base/ui_test_utils.h"
21 #include "components/app_modal/javascript_app_modal_dialog.h"
22 #include "components/app_modal/native_app_modal_dialog.h"
23 #include "content/public/browser/browser_thread.h"
24 #include "content/public/browser/notification_service.h"
25 #include "content/public/browser/web_contents.h"
26 #include "content/public/test/browser_test_utils.h"
27 #include "net/test/url_request/url_request_mock_http_job.h"
28 #include "net/url_request/url_request_test_util.h"
31 // For version specific disabled tests below (http://crbug.com/267597).
32 #include "base/win/windows_version.h"
35 using base::TimeDelta
;
36 using content::BrowserThread
;
38 const std::string NOLISTENERS_HTML
=
39 "<html><head><title>nolisteners</title></head><body></body></html>";
41 const std::string UNLOAD_HTML
=
42 "<html><head><title>unload</title></head><body>"
43 "<script>window.onunload=function(e){}</script></body></html>";
45 const std::string BEFORE_UNLOAD_HTML
=
46 "<html><head><title>beforeunload</title></head><body>"
47 "<script>window.onbeforeunload=function(e){"
48 "setTimeout('document.title=\"cancelled\"', 0);return 'foo'}</script>"
51 const std::string INNER_FRAME_WITH_FOCUS_HTML
=
52 "<html><head><title>innerframewithfocus</title></head><body>"
53 "<script>window.onbeforeunload=function(e){return 'foo'}</script>"
54 "<iframe src=\"data:text/html,<html><head><script>window.onload="
55 "function(){document.getElementById('box').focus()}</script>"
56 "<body><input id='box'></input></body></html>\"></iframe>"
59 const std::string TWO_SECOND_BEFORE_UNLOAD_HTML
=
60 "<html><head><title>twosecondbeforeunload</title></head><body>"
61 "<script>window.onbeforeunload=function(e){"
62 "var start = new Date().getTime();"
63 "while(new Date().getTime() - start < 2000){}"
65 "}</script></body></html>";
67 const std::string INFINITE_UNLOAD_HTML
=
68 "<html><head><title>infiniteunload</title></head><body>"
69 "<script>window.onunload=function(e){while(true){}}</script>"
72 const std::string INFINITE_BEFORE_UNLOAD_HTML
=
73 "<html><head><title>infinitebeforeunload</title></head><body>"
74 "<script>window.onbeforeunload=function(e){while(true){}}</script>"
77 const std::string INFINITE_UNLOAD_ALERT_HTML
=
78 "<html><head><title>infiniteunloadalert</title></head><body>"
79 "<script>window.onunload=function(e){"
82 "}</script></body></html>";
84 const std::string INFINITE_BEFORE_UNLOAD_ALERT_HTML
=
85 "<html><head><title>infinitebeforeunloadalert</title></head><body>"
86 "<script>window.onbeforeunload=function(e){"
89 "}</script></body></html>";
91 const std::string TWO_SECOND_UNLOAD_ALERT_HTML
=
92 "<html><head><title>twosecondunloadalert</title></head><body>"
93 "<script>window.onunload=function(e){"
94 "var start = new Date().getTime();"
95 "while(new Date().getTime() - start < 2000){}"
97 "}</script></body></html>";
99 const std::string TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML
=
100 "<html><head><title>twosecondbeforeunloadalert</title></head><body>"
101 "<script>window.onbeforeunload=function(e){"
102 "var start = new Date().getTime();"
103 "while(new Date().getTime() - start < 2000){}"
105 "}</script></body></html>";
107 const std::string CLOSE_TAB_WHEN_OTHER_TAB_HAS_LISTENER
=
108 "<html><head><title>only_one_unload</title></head>"
109 "<body onclick=\"window.open('data:text/html,"
110 "<html><head><title>popup</title></head></body>')\" "
111 "onbeforeunload='return;'>"
114 class UnloadTest
: public InProcessBrowserTest
{
116 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
117 const testing::TestInfo
* const test_info
=
118 testing::UnitTest::GetInstance()->current_test_info();
119 if (strcmp(test_info
->name(),
120 "BrowserCloseTabWhenOtherTabHasListener") == 0) {
121 command_line
->AppendSwitch(switches::kDisablePopupBlocking
);
122 } else if (strcmp(test_info
->name(), "BrowserTerminateBeforeUnload") == 0) {
123 #if defined(OS_POSIX)
124 DisableSIGTERMHandling();
129 void SetUpOnMainThread() override
{
130 BrowserThread::PostTask(
131 BrowserThread::IO
, FROM_HERE
,
132 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
135 void CheckTitle(const char* expected_title
) {
136 base::string16 expected
= base::ASCIIToUTF16(expected_title
);
138 browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
141 void NavigateToDataURL(const std::string
& html_content
,
142 const char* expected_title
) {
143 ui_test_utils::NavigateToURL(browser(),
144 GURL("data:text/html," + html_content
));
145 CheckTitle(expected_title
);
148 void NavigateToNolistenersFileTwice() {
149 GURL
url(net::URLRequestMockHTTPJob::GetMockUrl(
150 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
151 ui_test_utils::NavigateToURL(browser(), url
);
152 CheckTitle("Title Of Awesomeness");
153 ui_test_utils::NavigateToURL(browser(), url
);
154 CheckTitle("Title Of Awesomeness");
157 // Navigates to a URL asynchronously, then again synchronously. The first
158 // load is purposely async to test the case where the user loads another
159 // page without waiting for the first load to complete.
160 void NavigateToNolistenersFileTwiceAsync() {
161 GURL
url(net::URLRequestMockHTTPJob::GetMockUrl(
162 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
163 ui_test_utils::NavigateToURLWithDisposition(browser(), url
, CURRENT_TAB
, 0);
164 ui_test_utils::NavigateToURL(browser(), url
);
165 CheckTitle("Title Of Awesomeness");
168 void LoadUrlAndQuitBrowser(const std::string
& html_content
,
169 const char* expected_title
) {
170 NavigateToDataURL(html_content
, expected_title
);
171 content::WindowedNotificationObserver
window_observer(
172 chrome::NOTIFICATION_BROWSER_CLOSED
,
173 content::NotificationService::AllSources());
174 chrome::CloseWindow(browser());
175 window_observer
.Wait();
178 // If |accept| is true, simulates user clicking OK, otherwise simulates
180 void ClickModalDialogButton(bool accept
) {
181 app_modal::AppModalDialog
* dialog
= ui_test_utils::WaitForAppModalDialog();
182 ASSERT_TRUE(dialog
->IsJavaScriptModalDialog());
183 app_modal::JavaScriptAppModalDialog
* js_dialog
=
184 static_cast<app_modal::JavaScriptAppModalDialog
*>(dialog
);
186 js_dialog
->native_dialog()->AcceptAppModalDialog();
188 js_dialog
->native_dialog()->CancelAppModalDialog();
192 // Navigate to a page with an infinite unload handler.
193 // Then two async crosssite requests to ensure
194 // we don't get confused and think we're closing the tab.
196 // This test is flaky on the valgrind UI bots. http://crbug.com/39057
197 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteUnloadAsync
) {
198 // Tests makes no sense in single-process mode since the renderer is hung.
199 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
200 switches::kSingleProcess
))
203 NavigateToDataURL(INFINITE_UNLOAD_HTML
, "infiniteunload");
204 // Must navigate to a non-data URL to trigger cross-site codepath.
205 NavigateToNolistenersFileTwiceAsync();
208 // Navigate to a page with an infinite unload handler.
209 // Then two sync crosssite requests to ensure
210 // we correctly nav to each one.
211 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteUnloadSync
) {
212 // Tests makes no sense in single-process mode since the renderer is hung.
213 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
214 switches::kSingleProcess
))
217 NavigateToDataURL(INFINITE_UNLOAD_HTML
, "infiniteunload");
218 // Must navigate to a non-data URL to trigger cross-site codepath.
219 NavigateToNolistenersFileTwice();
222 // Navigate to a page with an infinite beforeunload handler.
223 // Then two two async crosssite requests to ensure
224 // we don't get confused and think we're closing the tab.
225 // This test is flaky on the valgrind UI bots. http://crbug.com/39057 and
226 // http://crbug.com/86469
227 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteBeforeUnloadAsync
) {
228 // Tests makes no sense in single-process mode since the renderer is hung.
229 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
230 switches::kSingleProcess
))
233 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML
, "infinitebeforeunload");
234 // Must navigate to a non-data URL to trigger cross-site codepath.
235 NavigateToNolistenersFileTwiceAsync();
238 // Navigate to a page with an infinite beforeunload handler.
239 // Then two two sync crosssite requests to ensure
240 // we correctly nav to each one.
241 // Flaky on Win, Linux, and Mac; http://crbug.com/462671.
242 IN_PROC_BROWSER_TEST_F(UnloadTest
, DISABLED_CrossSiteInfiniteBeforeUnloadSync
) {
243 // Tests makes no sense in single-process mode since the renderer is hung.
244 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
245 switches::kSingleProcess
))
248 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML
, "infinitebeforeunload");
249 // Must navigate to a non-data URL to trigger cross-site codepath.
250 NavigateToNolistenersFileTwice();
253 // Tests closing the browser on a page with no unload listeners registered.
254 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseNoUnloadListeners
) {
255 LoadUrlAndQuitBrowser(NOLISTENERS_HTML
, "nolisteners");
258 // Tests closing the browser on a page with an unload listener registered.
259 // Test marked as flaky in http://crbug.com/51698
260 IN_PROC_BROWSER_TEST_F(UnloadTest
, DISABLED_BrowserCloseUnload
) {
261 LoadUrlAndQuitBrowser(UNLOAD_HTML
, "unload");
264 // Tests closing the browser with a beforeunload handler and clicking
265 // OK in the beforeunload confirm dialog.
266 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseBeforeUnloadOK
) {
267 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
269 content::WindowedNotificationObserver
window_observer(
270 chrome::NOTIFICATION_BROWSER_CLOSED
,
271 content::NotificationService::AllSources());
272 chrome::CloseWindow(browser());
273 ClickModalDialogButton(true);
274 window_observer
.Wait();
277 // Tests closing the browser with a beforeunload handler and clicking
278 // CANCEL in the beforeunload confirm dialog.
279 // If this test flakes, reopen http://crbug.com/123110
280 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseBeforeUnloadCancel
) {
281 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
282 chrome::CloseWindow(browser());
284 // We wait for the title to change after cancelling the popup to ensure that
285 // in-flight IPCs from the renderer reach the browser. Otherwise the browser
286 // won't put up the beforeunload dialog because it's waiting for an ack from
288 base::string16 expected_title
= base::ASCIIToUTF16("cancelled");
289 content::TitleWatcher
title_watcher(
290 browser()->tab_strip_model()->GetActiveWebContents(), expected_title
);
291 ClickModalDialogButton(false);
292 ASSERT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
294 content::WindowedNotificationObserver
window_observer(
295 chrome::NOTIFICATION_BROWSER_CLOSED
,
296 content::NotificationService::AllSources());
297 chrome::CloseWindow(browser());
298 ClickModalDialogButton(true);
299 window_observer
.Wait();
302 // Tests terminating the browser with a beforeunload handler.
303 // Currently only ChromeOS shuts down gracefully.
304 #if defined(OS_CHROMEOS)
305 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserTerminateBeforeUnload
) {
306 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
307 EXPECT_EQ(kill(base::GetCurrentProcessHandle(), SIGTERM
), 0);
311 // Tests closing the browser and clicking OK in the beforeunload confirm dialog
312 // if an inner frame has the focus.
313 // If this flakes, use http://crbug.com/32615 and http://crbug.com/45675
314 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseWithInnerFocusedFrame
) {
315 NavigateToDataURL(INNER_FRAME_WITH_FOCUS_HTML
, "innerframewithfocus");
317 content::WindowedNotificationObserver
window_observer(
318 chrome::NOTIFICATION_BROWSER_CLOSED
,
319 content::NotificationService::AllSources());
320 chrome::CloseWindow(browser());
321 ClickModalDialogButton(true);
322 window_observer
.Wait();
325 // Tests closing the browser with a beforeunload handler that takes
326 // two seconds to run.
327 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTwoSecondBeforeUnload
) {
328 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_HTML
,
329 "twosecondbeforeunload");
332 // Tests closing the browser on a page with an unload listener registered where
333 // the unload handler has an infinite loop.
334 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseInfiniteUnload
) {
335 // Tests makes no sense in single-process mode since the renderer is hung.
336 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
337 switches::kSingleProcess
))
340 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_HTML
, "infiniteunload");
343 // Tests closing the browser with a beforeunload handler that hangs.
344 // If this flakes, use http://crbug.com/78803 and http://crbug.com/86469
345 IN_PROC_BROWSER_TEST_F(UnloadTest
, DISABLED_BrowserCloseInfiniteBeforeUnload
) {
346 // Tests makes no sense in single-process mode since the renderer is hung.
347 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
348 switches::kSingleProcess
))
351 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_HTML
, "infinitebeforeunload");
354 // Tests closing the browser on a page with an unload listener registered where
355 // the unload handler has an infinite loop followed by an alert.
356 // If this flakes, use http://crbug.com/86469
357 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseInfiniteUnloadAlert
) {
358 // Tests makes no sense in single-process mode since the renderer is hung.
359 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
360 switches::kSingleProcess
))
363 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_ALERT_HTML
, "infiniteunloadalert");
366 // Tests closing the browser with a beforeunload handler that hangs then
368 // If this flakes, use http://crbug.com/78803 and http://crbug.com/86469.
369 IN_PROC_BROWSER_TEST_F(UnloadTest
,
370 DISABLED_BrowserCloseInfiniteBeforeUnloadAlert
) {
371 // Tests makes no sense in single-process mode since the renderer is hung.
372 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
373 switches::kSingleProcess
))
376 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_ALERT_HTML
,
377 "infinitebeforeunloadalert");
380 // Tests closing the browser on a page with an unload listener registered where
381 // the unload handler has an 2 second long loop followed by an alert.
382 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTwoSecondUnloadAlert
) {
383 LoadUrlAndQuitBrowser(TWO_SECOND_UNLOAD_ALERT_HTML
, "twosecondunloadalert");
386 // Tests closing the browser with a beforeunload handler that takes
387 // two seconds to run then pops up an alert.
388 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTwoSecondBeforeUnloadAlert
) {
389 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML
,
390 "twosecondbeforeunloadalert");
393 // Tests that if there's a renderer process with two tabs, one of which has an
394 // unload handler, and the other doesn't, the tab that doesn't have an unload
395 // handler can be closed.
396 // If this flakes, see http://crbug.com/45162, http://crbug.com/45281 and
397 // http://crbug.com/86769.
398 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTabWhenOtherTabHasListener
) {
399 NavigateToDataURL(CLOSE_TAB_WHEN_OTHER_TAB_HAS_LISTENER
, "only_one_unload");
401 // Simulate a click to force user_gesture to true; if we don't, the resulting
402 // popup will be constrained, which isn't what we want to test.
404 content::WindowedNotificationObserver
observer(
405 chrome::NOTIFICATION_TAB_ADDED
,
406 content::NotificationService::AllSources());
407 content::WindowedNotificationObserver
load_stop_observer(
408 content::NOTIFICATION_LOAD_STOP
,
409 content::NotificationService::AllSources());
410 content::SimulateMouseClick(
411 browser()->tab_strip_model()->GetActiveWebContents(), 0,
412 blink::WebMouseEvent::ButtonLeft
);
414 load_stop_observer
.Wait();
417 content::WebContentsDestroyedWatcher
destroyed_watcher(
418 browser()->tab_strip_model()->GetActiveWebContents());
419 chrome::CloseTab(browser());
420 destroyed_watcher
.Wait();
422 CheckTitle("only_one_unload");
425 class FastUnloadTest
: public UnloadTest
{
427 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
428 UnloadTest::SetUpCommandLine(command_line
);
429 command_line
->AppendSwitch(switches::kEnableFastUnload
);
432 void SetUpInProcessBrowserTestFixture() override
{
433 ASSERT_TRUE(test_server()->Start());
436 void TearDownInProcessBrowserTestFixture() override
{ test_server()->Stop(); }
438 GURL
GetUrl(const std::string
& name
) {
439 return GURL(test_server()->GetURL(
440 "files/fast_tab_close/" + name
+ ".html"));
443 void NavigateToPage(const char* name
) {
444 ui_test_utils::NavigateToURL(browser(), GetUrl(name
));
448 void NavigateToPageInNewTab(const char* name
) {
449 ui_test_utils::NavigateToURLWithDisposition(
450 browser(), GetUrl(name
), NEW_FOREGROUND_TAB
,
451 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
455 std::string
GetCookies(const char* name
) {
456 content::WebContents
* contents
=
457 browser()->tab_strip_model()->GetActiveWebContents();
458 return content::GetCookies(contents
->GetBrowserContext(), GetUrl(name
));
462 class FastTabCloseTabStripModelObserver
: public TabStripModelObserver
{
464 FastTabCloseTabStripModelObserver(TabStripModel
* model
,
465 base::RunLoop
* run_loop
)
467 run_loop_(run_loop
) {
468 model_
->AddObserver(this);
471 ~FastTabCloseTabStripModelObserver() override
{
472 model_
->RemoveObserver(this);
475 // TabStripModelObserver:
476 void TabDetachedAt(content::WebContents
* contents
, int index
) override
{
481 TabStripModel
* const model_
;
482 base::RunLoop
* const run_loop_
;
486 // Test that fast-tab-close works when closing a tab with an unload handler
487 // (http://crbug.com/142458).
488 // Flaky on Windows bots (http://crbug.com/267597).
490 #define MAYBE_UnloadHidden \
491 DISABLED_UnloadHidden
493 #define MAYBE_UnloadHidden \
496 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, MAYBE_UnloadHidden
) {
497 NavigateToPage("no_listeners");
498 NavigateToPageInNewTab("unload_sets_cookie");
499 EXPECT_EQ("", GetCookies("no_listeners"));
501 content::WebContentsDestroyedWatcher
destroyed_watcher(
502 browser()->tab_strip_model()->GetActiveWebContents());
505 base::RunLoop run_loop
;
506 FastTabCloseTabStripModelObserver
observer(
507 browser()->tab_strip_model(), &run_loop
);
508 chrome::CloseTab(browser());
512 // Check that the browser only has the original tab.
513 CheckTitle("no_listeners");
514 EXPECT_EQ(1, browser()->tab_strip_model()->count());
516 // Wait for the actual destruction.
517 destroyed_watcher
.Wait();
519 // Verify that the destruction had the desired effect.
520 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
523 // Test that fast-tab-close does not break a solo tab.
524 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, PRE_ClosingLastTabFinishesUnload
) {
525 // The unload handler sleeps before setting the cookie to catch cases when
526 // unload handlers are not allowed to run to completion. (For example,
527 // using the detached handler for the tab and then closing the browser.)
528 NavigateToPage("unload_sleep_before_cookie");
529 EXPECT_EQ(1, browser()->tab_strip_model()->count());
530 EXPECT_EQ("", GetCookies("unload_sleep_before_cookie"));
532 content::WindowedNotificationObserver
window_observer(
533 chrome::NOTIFICATION_BROWSER_CLOSED
,
534 content::NotificationService::AllSources());
535 chrome::CloseTab(browser());
536 window_observer
.Wait();
539 // Fails on Mac, Linux, Win7 (http://crbug.com/301173).
540 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, DISABLED_ClosingLastTabFinishesUnload
) {
542 // Flaky on Win7+ bots (http://crbug.com/267597).
543 if (base::win::GetVersion() >= base::win::VERSION_WIN7
)
546 // Check for cookie set in unload handler of PRE_ test.
547 NavigateToPage("no_listeners");
548 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
551 // Test that fast-tab-close does not break window close.
552 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, PRE_WindowCloseFinishesUnload
) {
553 NavigateToPage("no_listeners");
555 // The unload handler sleeps before setting the cookie to catch cases when
556 // unload handlers are not allowed to run to completion. Without the sleep,
557 // the cookie can get set even if the browser does not wait for
558 // the unload handler to finish.
559 NavigateToPageInNewTab("unload_sleep_before_cookie");
560 EXPECT_EQ(2, browser()->tab_strip_model()->count());
561 EXPECT_EQ("", GetCookies("no_listeners"));
563 content::WindowedNotificationObserver
window_observer(
564 chrome::NOTIFICATION_BROWSER_CLOSED
,
565 content::NotificationService::AllSources());
566 chrome::CloseWindow(browser());
567 window_observer
.Wait();
570 // Flaky on Windows bots (http://crbug.com/279267) and fails on Mac / Linux bots
571 // (http://crbug.com/301173).
572 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, DISABLED_WindowCloseFinishesUnload
) {
573 // Check for cookie set in unload during PRE_ test.
574 NavigateToPage("no_listeners");
575 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
578 // Test that a tab crash during unload does not break window close.
580 // Hits assertion on Linux and Mac:
581 // [FATAL:profile_destroyer.cc(46)] Check failed:
583 // profile->IsOffTheRecord() ||
584 // content::RenderProcessHost::run_renderer_in_process().
585 // More details: The renderer process host matches the closed, crashed tab.
586 // The |UnloadController| receives |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|
587 // and proceeds with the close.
588 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, DISABLED_WindowCloseAfterUnloadCrash
) {
589 NavigateToPage("no_listeners");
590 NavigateToPageInNewTab("unload_sets_cookie");
591 content::WebContents
* unload_contents
=
592 browser()->tab_strip_model()->GetActiveWebContents();
593 EXPECT_EQ("", GetCookies("no_listeners"));
596 base::RunLoop run_loop
;
597 FastTabCloseTabStripModelObserver
observer(
598 browser()->tab_strip_model(), &run_loop
);
599 chrome::CloseTab(browser());
603 // Check that the browser only has the original tab.
604 CheckTitle("no_listeners");
605 EXPECT_EQ(1, browser()->tab_strip_model()->count());
607 CrashTab(unload_contents
);
609 // Check that the browser only has the original tab.
610 CheckTitle("no_listeners");
611 EXPECT_EQ(1, browser()->tab_strip_model()->count());
613 content::WindowedNotificationObserver
window_observer(
614 chrome::NOTIFICATION_BROWSER_CLOSED
,
615 content::NotificationService::AllSources());
616 chrome::CloseWindow(browser());
617 window_observer
.Wait();
620 // Times out on Windows and Linux.
621 #if defined(OS_WIN) || defined(OS_LINUX)
622 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
623 DISABLED_WindowCloseAfterBeforeUnloadCrash
625 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
626 WindowCloseAfterBeforeUnloadCrash
628 IN_PROC_BROWSER_TEST_F(FastUnloadTest
,
629 MAYBE_WindowCloseAfterBeforeUnloadCrash
) {
630 // Tests makes no sense in single-process mode since the renderer is hung.
631 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
632 switches::kSingleProcess
))
635 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
636 content::WebContents
* beforeunload_contents
=
637 browser()->tab_strip_model()->GetActiveWebContents();
639 content::WindowedNotificationObserver
window_observer(
640 chrome::NOTIFICATION_BROWSER_CLOSED
,
641 content::NotificationService::AllSources());
642 chrome::CloseWindow(browser());
643 CrashTab(beforeunload_contents
);
644 window_observer
.Wait();
647 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs
648 // and multiple windows.