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/process_util.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "chrome/browser/net/url_request_mock_util.h"
14 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h"
15 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h"
16 #include "chrome/browser/ui/browser.h"
17 #include "chrome/browser/ui/browser_commands.h"
18 #include "chrome/browser/ui/browser_list.h"
19 #include "chrome/browser/ui/tabs/tab_strip_model.h"
20 #include "chrome/common/chrome_notification_types.h"
21 #include "chrome/common/chrome_switches.h"
22 #include "chrome/test/base/in_process_browser_test.h"
23 #include "chrome/test/base/ui_test_utils.h"
24 #include "content/public/browser/browser_thread.h"
25 #include "content/public/browser/notification_service.h"
26 #include "content/public/browser/web_contents.h"
27 #include "content/public/test/browser_test_utils.h"
28 #include "content/test/net/url_request_mock_http_job.h"
29 #include "net/url_request/url_request_test_util.h"
31 using base::TimeDelta
;
32 using content::BrowserThread
;
34 const std::string NOLISTENERS_HTML
=
35 "<html><head><title>nolisteners</title></head><body></body></html>";
37 const std::string UNLOAD_HTML
=
38 "<html><head><title>unload</title></head><body>"
39 "<script>window.onunload=function(e){}</script></body></html>";
41 const std::string BEFORE_UNLOAD_HTML
=
42 "<html><head><title>beforeunload</title></head><body>"
43 "<script>window.onbeforeunload=function(e){"
44 "setTimeout('document.title=\"cancelled\"', 0);return 'foo'}</script>"
47 const std::string INNER_FRAME_WITH_FOCUS_HTML
=
48 "<html><head><title>innerframewithfocus</title></head><body>"
49 "<script>window.onbeforeunload=function(e){return 'foo'}</script>"
50 "<iframe src=\"data:text/html,<html><head><script>window.onload="
51 "function(){document.getElementById('box').focus()}</script>"
52 "<body><input id='box'></input></body></html>\"></iframe>"
55 const std::string TWO_SECOND_BEFORE_UNLOAD_HTML
=
56 "<html><head><title>twosecondbeforeunload</title></head><body>"
57 "<script>window.onbeforeunload=function(e){"
58 "var start = new Date().getTime();"
59 "while(new Date().getTime() - start < 2000){}"
61 "}</script></body></html>";
63 const std::string INFINITE_UNLOAD_HTML
=
64 "<html><head><title>infiniteunload</title></head><body>"
65 "<script>window.onunload=function(e){while(true){}}</script>"
68 const std::string INFINITE_BEFORE_UNLOAD_HTML
=
69 "<html><head><title>infinitebeforeunload</title></head><body>"
70 "<script>window.onbeforeunload=function(e){while(true){}}</script>"
73 const std::string INFINITE_UNLOAD_ALERT_HTML
=
74 "<html><head><title>infiniteunloadalert</title></head><body>"
75 "<script>window.onunload=function(e){"
78 "}</script></body></html>";
80 const std::string INFINITE_BEFORE_UNLOAD_ALERT_HTML
=
81 "<html><head><title>infinitebeforeunloadalert</title></head><body>"
82 "<script>window.onbeforeunload=function(e){"
85 "}</script></body></html>";
87 const std::string TWO_SECOND_UNLOAD_ALERT_HTML
=
88 "<html><head><title>twosecondunloadalert</title></head><body>"
89 "<script>window.onunload=function(e){"
90 "var start = new Date().getTime();"
91 "while(new Date().getTime() - start < 2000){}"
93 "}</script></body></html>";
95 const std::string TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML
=
96 "<html><head><title>twosecondbeforeunloadalert</title></head><body>"
97 "<script>window.onbeforeunload=function(e){"
98 "var start = new Date().getTime();"
99 "while(new Date().getTime() - start < 2000){}"
101 "}</script></body></html>";
103 const std::string CLOSE_TAB_WHEN_OTHER_TAB_HAS_LISTENER
=
104 "<html><head><title>only_one_unload</title></head>"
105 "<body onclick=\"window.open('data:text/html,"
106 "<html><head><title>popup</title></head></body>')\" "
107 "onbeforeunload='return;'>"
110 class UnloadTest
: public InProcessBrowserTest
{
112 virtual void SetUpCommandLine(CommandLine
* command_line
) OVERRIDE
{
113 const testing::TestInfo
* const test_info
=
114 testing::UnitTest::GetInstance()->current_test_info();
115 if (strcmp(test_info
->name(),
116 "BrowserCloseTabWhenOtherTabHasListener") == 0) {
117 command_line
->AppendSwitch(switches::kDisablePopupBlocking
);
118 } else if (strcmp(test_info
->name(), "BrowserTerminateBeforeUnload") == 0) {
119 #if defined(OS_POSIX)
120 DisableSIGTERMHandling();
125 virtual void SetUpOnMainThread() OVERRIDE
{
126 BrowserThread::PostTask(
127 BrowserThread::IO
, FROM_HERE
,
128 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
131 void CheckTitle(const char* expected_title
) {
132 string16 expected
= ASCIIToUTF16(expected_title
);
134 browser()->tab_strip_model()->GetActiveWebContents()->GetTitle());
137 void NavigateToDataURL(const std::string
& html_content
,
138 const char* expected_title
) {
139 ui_test_utils::NavigateToURL(browser(),
140 GURL("data:text/html," + html_content
));
141 CheckTitle(expected_title
);
144 void NavigateToNolistenersFileTwice() {
145 GURL
url(content::URLRequestMockHTTPJob::GetMockUrl(
146 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
147 ui_test_utils::NavigateToURL(browser(), url
);
148 CheckTitle("Title Of Awesomeness");
149 ui_test_utils::NavigateToURL(browser(), url
);
150 CheckTitle("Title Of Awesomeness");
153 // Navigates to a URL asynchronously, then again synchronously. The first
154 // load is purposely async to test the case where the user loads another
155 // page without waiting for the first load to complete.
156 void NavigateToNolistenersFileTwiceAsync() {
157 GURL
url(content::URLRequestMockHTTPJob::GetMockUrl(
158 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
159 ui_test_utils::NavigateToURLWithDisposition(browser(), url
, CURRENT_TAB
, 0);
160 ui_test_utils::NavigateToURL(browser(), url
);
161 CheckTitle("Title Of Awesomeness");
164 void LoadUrlAndQuitBrowser(const std::string
& html_content
,
165 const char* expected_title
) {
166 NavigateToDataURL(html_content
, expected_title
);
167 content::WindowedNotificationObserver
window_observer(
168 chrome::NOTIFICATION_BROWSER_CLOSED
,
169 content::NotificationService::AllSources());
170 chrome::CloseWindow(browser());
171 window_observer
.Wait();
174 // If |accept| is true, simulates user clicking OK, otherwise simulates
176 void ClickModalDialogButton(bool accept
) {
177 AppModalDialog
* dialog
= ui_test_utils::WaitForAppModalDialog();
178 ASSERT_TRUE(dialog
->IsJavaScriptModalDialog());
179 JavaScriptAppModalDialog
* js_dialog
=
180 static_cast<JavaScriptAppModalDialog
*>(dialog
);
182 js_dialog
->native_dialog()->AcceptAppModalDialog();
184 js_dialog
->native_dialog()->CancelAppModalDialog();
188 // Navigate to a page with an infinite unload handler.
189 // Then two async crosssite requests to ensure
190 // we don't get confused and think we're closing the tab.
192 // This test is flaky on the valgrind UI bots. http://crbug.com/39057
193 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteUnloadAsync
) {
194 // Tests makes no sense in single-process mode since the renderer is hung.
195 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
198 NavigateToDataURL(INFINITE_UNLOAD_HTML
, "infiniteunload");
199 // Must navigate to a non-data URL to trigger cross-site codepath.
200 NavigateToNolistenersFileTwiceAsync();
203 // Navigate to a page with an infinite unload handler.
204 // Then two sync crosssite requests to ensure
205 // we correctly nav to each one.
206 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteUnloadSync
) {
207 // Tests makes no sense in single-process mode since the renderer is hung.
208 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
211 NavigateToDataURL(INFINITE_UNLOAD_HTML
, "infiniteunload");
212 // Must navigate to a non-data URL to trigger cross-site codepath.
213 NavigateToNolistenersFileTwice();
216 // Navigate to a page with an infinite beforeunload handler.
217 // Then two two async crosssite requests to ensure
218 // we don't get confused and think we're closing the tab.
219 // This test is flaky on the valgrind UI bots. http://crbug.com/39057 and
220 // http://crbug.com/86469
221 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteBeforeUnloadAsync
) {
222 // Tests makes no sense in single-process mode since the renderer is hung.
223 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
226 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML
, "infinitebeforeunload");
227 // Must navigate to a non-data URL to trigger cross-site codepath.
228 NavigateToNolistenersFileTwiceAsync();
231 // Navigate to a page with an infinite beforeunload handler.
232 // Then two two sync crosssite requests to ensure
233 // we correctly nav to each one.
234 // If this flakes, see bug http://crbug.com/86469.
235 IN_PROC_BROWSER_TEST_F(UnloadTest
, CrossSiteInfiniteBeforeUnloadSync
) {
236 // Tests makes no sense in single-process mode since the renderer is hung.
237 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
240 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML
, "infinitebeforeunload");
241 // Must navigate to a non-data URL to trigger cross-site codepath.
242 NavigateToNolistenersFileTwice();
245 // Tests closing the browser on a page with no unload listeners registered.
246 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseNoUnloadListeners
) {
247 LoadUrlAndQuitBrowser(NOLISTENERS_HTML
, "nolisteners");
250 // Tests closing the browser on a page with an unload listener registered.
251 // Test marked as flaky in http://crbug.com/51698
252 IN_PROC_BROWSER_TEST_F(UnloadTest
, DISABLED_BrowserCloseUnload
) {
253 LoadUrlAndQuitBrowser(UNLOAD_HTML
, "unload");
256 // Tests closing the browser with a beforeunload handler and clicking
257 // OK in the beforeunload confirm dialog.
258 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseBeforeUnloadOK
) {
259 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
261 content::WindowedNotificationObserver
window_observer(
262 chrome::NOTIFICATION_BROWSER_CLOSED
,
263 content::NotificationService::AllSources());
264 chrome::CloseWindow(browser());
265 ClickModalDialogButton(true);
266 window_observer
.Wait();
269 // Tests closing the browser with a beforeunload handler and clicking
270 // CANCEL in the beforeunload confirm dialog.
271 // If this test flakes, reopen http://crbug.com/123110
272 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseBeforeUnloadCancel
) {
273 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
274 chrome::CloseWindow(browser());
276 // We wait for the title to change after cancelling the popup to ensure that
277 // in-flight IPCs from the renderer reach the browser. Otherwise the browser
278 // won't put up the beforeunload dialog because it's waiting for an ack from
280 string16 expected_title
= ASCIIToUTF16("cancelled");
281 content::TitleWatcher
title_watcher(
282 browser()->tab_strip_model()->GetActiveWebContents(), expected_title
);
283 ClickModalDialogButton(false);
284 ASSERT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
286 content::WindowedNotificationObserver
window_observer(
287 chrome::NOTIFICATION_BROWSER_CLOSED
,
288 content::NotificationService::AllSources());
289 chrome::CloseWindow(browser());
290 ClickModalDialogButton(true);
291 window_observer
.Wait();
294 // Tests terminating the browser with a beforeunload handler.
295 // Currently only ChromeOS shuts down gracefully.
296 #if defined(OS_CHROMEOS)
297 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserTerminateBeforeUnload
) {
298 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
299 EXPECT_EQ(kill(base::GetCurrentProcessHandle(), SIGTERM
), 0);
303 // Tests closing the browser and clicking OK in the beforeunload confirm dialog
304 // if an inner frame has the focus.
305 // If this flakes, use http://crbug.com/32615 and http://crbug.com/45675
306 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseWithInnerFocusedFrame
) {
307 NavigateToDataURL(INNER_FRAME_WITH_FOCUS_HTML
, "innerframewithfocus");
309 content::WindowedNotificationObserver
window_observer(
310 chrome::NOTIFICATION_BROWSER_CLOSED
,
311 content::NotificationService::AllSources());
312 chrome::CloseWindow(browser());
313 ClickModalDialogButton(true);
314 window_observer
.Wait();
317 // Tests closing the browser with a beforeunload handler that takes
318 // two seconds to run.
319 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTwoSecondBeforeUnload
) {
320 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_HTML
,
321 "twosecondbeforeunload");
324 // Tests closing the browser on a page with an unload listener registered where
325 // the unload handler has an infinite loop.
326 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseInfiniteUnload
) {
327 // Tests makes no sense in single-process mode since the renderer is hung.
328 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
331 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_HTML
, "infiniteunload");
334 // Tests closing the browser with a beforeunload handler that hangs.
335 // If this flakes, use http://crbug.com/78803 and http://crbug.com/86469
336 IN_PROC_BROWSER_TEST_F(UnloadTest
, DISABLED_BrowserCloseInfiniteBeforeUnload
) {
337 // Tests makes no sense in single-process mode since the renderer is hung.
338 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
341 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_HTML
, "infinitebeforeunload");
344 // Tests closing the browser on a page with an unload listener registered where
345 // the unload handler has an infinite loop followed by an alert.
346 // If this flakes, use http://crbug.com/86469
347 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseInfiniteUnloadAlert
) {
348 // Tests makes no sense in single-process mode since the renderer is hung.
349 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
352 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_ALERT_HTML
, "infiniteunloadalert");
355 // Tests closing the browser with a beforeunload handler that hangs then
357 // If this flakes, use http://crbug.com/78803 and http://crbug.com/86469.
358 IN_PROC_BROWSER_TEST_F(UnloadTest
,
359 DISABLED_BrowserCloseInfiniteBeforeUnloadAlert
) {
360 // Tests makes no sense in single-process mode since the renderer is hung.
361 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
364 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_ALERT_HTML
,
365 "infinitebeforeunloadalert");
368 // Tests closing the browser on a page with an unload listener registered where
369 // the unload handler has an 2 second long loop followed by an alert.
370 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTwoSecondUnloadAlert
) {
371 LoadUrlAndQuitBrowser(TWO_SECOND_UNLOAD_ALERT_HTML
, "twosecondunloadalert");
374 // Tests closing the browser with a beforeunload handler that takes
375 // two seconds to run then pops up an alert.
376 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTwoSecondBeforeUnloadAlert
) {
377 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML
,
378 "twosecondbeforeunloadalert");
381 // Tests that if there's a renderer process with two tabs, one of which has an
382 // unload handler, and the other doesn't, the tab that doesn't have an unload
383 // handler can be closed.
384 // If this flakes, see http://crbug.com/45162, http://crbug.com/45281 and
385 // http://crbug.com/86769.
386 IN_PROC_BROWSER_TEST_F(UnloadTest
, BrowserCloseTabWhenOtherTabHasListener
) {
387 NavigateToDataURL(CLOSE_TAB_WHEN_OTHER_TAB_HAS_LISTENER
, "only_one_unload");
389 // Simulate a click to force user_gesture to true; if we don't, the resulting
390 // popup will be constrained, which isn't what we want to test.
392 content::WindowedNotificationObserver
observer(
393 chrome::NOTIFICATION_TAB_ADDED
,
394 content::NotificationService::AllSources());
395 content::WindowedNotificationObserver
load_stop_observer(
396 content::NOTIFICATION_LOAD_STOP
,
397 content::NotificationService::AllSources());
398 content::SimulateMouseClick(
399 browser()->tab_strip_model()->GetActiveWebContents(), 0,
400 WebKit::WebMouseEvent::ButtonLeft
);
402 load_stop_observer
.Wait();
405 content::WindowedNotificationObserver
tab_close_observer(
406 content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
407 content::NotificationService::AllSources());
408 chrome::CloseTab(browser());
409 tab_close_observer
.Wait();
411 CheckTitle("only_one_unload");
415 class FastUnloadTest
: public UnloadTest
{
417 virtual void SetUpInProcessBrowserTestFixture() OVERRIDE
{
418 ASSERT_TRUE(test_server()->Start());
421 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE
{
422 test_server()->Stop();
425 GURL
GetUrl(const std::string
& name
) {
426 return GURL(test_server()->GetURL(
427 "files/fast_tab_close/" + name
+ ".html"));
430 void NavigateToPage(const char* name
) {
431 ui_test_utils::NavigateToURL(browser(), GetUrl(name
));
435 void NavigateToPageInNewTab(const char* name
) {
436 ui_test_utils::NavigateToURLWithDisposition(
437 browser(), GetUrl(name
), NEW_FOREGROUND_TAB
,
438 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
442 std::string
GetCookies(const char* name
) {
443 content::WebContents
* contents
=
444 browser()->tab_strip_model()->GetActiveWebContents();
445 return content::GetCookies(contents
->GetBrowserContext(), GetUrl(name
));
449 class FastTabCloseTabStripModelObserver
: public TabStripModelObserver
{
451 FastTabCloseTabStripModelObserver(TabStripModel
* model
,
452 base::RunLoop
* run_loop
)
454 run_loop_(run_loop
) {
455 model_
->AddObserver(this);
458 virtual ~FastTabCloseTabStripModelObserver() {
459 model_
->RemoveObserver(this);
462 // TabStripModelObserver:
463 virtual void TabDetachedAt(content::WebContents
* contents
,
464 int index
) OVERRIDE
{
469 TabStripModel
* const model_
;
470 base::RunLoop
* const run_loop_
;
474 // Test that fast-tab-close works when closing a tab with an unload handler
475 // (http://crbug.com/142458).
476 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, UnloadHidden
) {
477 NavigateToPage("no_listeners");
478 NavigateToPageInNewTab("unload_sets_cookie");
479 EXPECT_EQ("", GetCookies("no_listeners"));
482 base::RunLoop run_loop
;
483 FastTabCloseTabStripModelObserver
observer(
484 browser()->tab_strip_model(), &run_loop
);
485 chrome::CloseTab(browser());
489 // Check that the browser only has the original tab.
490 CheckTitle("no_listeners");
491 EXPECT_EQ(1, browser()->tab_strip_model()->count());
493 // Show that the web contents to go away after the was removed.
494 // Without unload-detached, this times-out because it happens earlier.
495 content::WindowedNotificationObserver
contents_destroyed_observer(
496 content::NOTIFICATION_WEB_CONTENTS_DESTROYED
,
497 content::NotificationService::AllSources());
498 contents_destroyed_observer
.Wait();
500 // Browser still has the same tab.
501 CheckTitle("no_listeners");
502 EXPECT_EQ(1, browser()->tab_strip_model()->count());
503 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
506 // Test that fast-tab-close does not break a solo tab.
507 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, PRE_ClosingLastTabFinishesUnload
) {
508 // The unload handler sleeps before setting the cookie to catch cases when
509 // unload handlers are not allowed to run to completion. (For example,
510 // using the detached handler for the tab and then closing the browser.)
511 NavigateToPage("unload_sleep_before_cookie");
512 EXPECT_EQ(1, browser()->tab_strip_model()->count());
513 EXPECT_EQ("", GetCookies("unload_sleep_before_cookie"));
515 content::WindowedNotificationObserver
window_observer(
516 chrome::NOTIFICATION_BROWSER_CLOSED
,
517 content::NotificationService::AllSources());
518 chrome::CloseTab(browser());
519 window_observer
.Wait();
521 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, ClosingLastTabFinishesUnload
) {
522 // Check for cookie set in unload handler of PRE_ test.
523 NavigateToPage("no_listeners");
524 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
527 // Test that fast-tab-close does not break window close.
528 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, PRE_WindowCloseFinishesUnload
) {
529 NavigateToPage("no_listeners");
531 // The unload handler sleeps before setting the cookie to catch cases when
532 // unload handlers are not allowed to run to completion. Without the sleep,
533 // the cookie can get set even if the browser does not wait for
534 // the unload handler to finish.
535 NavigateToPageInNewTab("unload_sleep_before_cookie");
536 EXPECT_EQ(2, browser()->tab_strip_model()->count());
537 EXPECT_EQ("", GetCookies("no_listeners"));
539 content::WindowedNotificationObserver
window_observer(
540 chrome::NOTIFICATION_BROWSER_CLOSED
,
541 content::NotificationService::AllSources());
542 chrome::CloseWindow(browser());
543 window_observer
.Wait();
545 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, WindowCloseFinishesUnload
) {
546 // Check for cookie set in unload during PRE_ test.
547 NavigateToPage("no_listeners");
548 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
551 // Test that a tab crash during unload does not break window close.
553 // Hits assertion on Linux and Mac:
554 // [FATAL:profile_destroyer.cc(46)] Check failed:
556 // profile->IsOffTheRecord() ||
557 // content::RenderProcessHost::run_renderer_in_process().
558 // More details: The renderer process host matches the closed, crashed tab.
559 // The |UnloadController| receives |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|
560 // and proceeds with the close.
561 IN_PROC_BROWSER_TEST_F(FastUnloadTest
, DISABLED_WindowCloseAfterUnloadCrash
) {
562 NavigateToPage("no_listeners");
563 NavigateToPageInNewTab("unload_sets_cookie");
564 content::WebContents
* unload_contents
=
565 browser()->tab_strip_model()->GetActiveWebContents();
566 EXPECT_EQ("", GetCookies("no_listeners"));
569 base::RunLoop run_loop
;
570 FastTabCloseTabStripModelObserver
observer(
571 browser()->tab_strip_model(), &run_loop
);
572 chrome::CloseTab(browser());
576 // Check that the browser only has the original tab.
577 CheckTitle("no_listeners");
578 EXPECT_EQ(1, browser()->tab_strip_model()->count());
580 CrashTab(unload_contents
);
582 // Check that the browser only has the original tab.
583 CheckTitle("no_listeners");
584 EXPECT_EQ(1, browser()->tab_strip_model()->count());
586 content::WindowedNotificationObserver
window_observer(
587 chrome::NOTIFICATION_BROWSER_CLOSED
,
588 content::NotificationService::AllSources());
589 chrome::CloseWindow(browser());
590 window_observer
.Wait();
593 // Times out on Windows and Linux.
594 #if defined(OS_WIN) || defined(OS_LINUX)
595 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
596 DISABLED_WindowCloseAfterBeforeUnloadCrash
598 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
599 WindowCloseAfterBeforeUnloadCrash
601 IN_PROC_BROWSER_TEST_F(FastUnloadTest
,
602 MAYBE_WindowCloseAfterBeforeUnloadCrash
) {
603 // Tests makes no sense in single-process mode since the renderer is hung.
604 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess
))
607 NavigateToDataURL(BEFORE_UNLOAD_HTML
, "beforeunload");
608 content::WebContents
* beforeunload_contents
=
609 browser()->tab_strip_model()->GetActiveWebContents();
611 content::WindowedNotificationObserver
window_observer(
612 chrome::NOTIFICATION_BROWSER_CLOSED
,
613 content::NotificationService::AllSources());
614 chrome::CloseWindow(browser());
615 CrashTab(beforeunload_contents
);
616 window_observer
.Wait();
619 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs
620 // and multiple windows.