Check USB device path access when prompting users to select a device.
[chromium-blink-merge.git] / chrome / browser / unload_browsertest.cc
blobc19dc051be47a38be733c1ddbff127ef60f4c9d6
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.
5 #if defined(OS_POSIX)
6 #include <signal.h>
7 #endif
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"
30 #if defined(OS_WIN)
31 // For version specific disabled tests below (http://crbug.com/267597).
32 #include "base/win/windows_version.h"
33 #endif
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>"
49 "</body></html>";
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>"
57 "</body></html>";
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){}"
64 "return 'foo';"
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>"
70 "</body></html>";
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>"
75 "</body></html>";
77 const std::string INFINITE_UNLOAD_ALERT_HTML =
78 "<html><head><title>infiniteunloadalert</title></head><body>"
79 "<script>window.onunload=function(e){"
80 "while(true){}"
81 "alert('foo');"
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){"
87 "while(true){}"
88 "alert('foo');"
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){}"
96 "alert('foo');"
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){}"
104 "alert('foo');"
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;'>"
112 "</body></html>";
114 class UnloadTest : public InProcessBrowserTest {
115 public:
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();
125 #endif
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);
137 EXPECT_EQ(expected,
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
179 // clicking Cancel.
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);
185 if (accept)
186 js_dialog->native_dialog()->AcceptAppModalDialog();
187 else
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))
201 return;
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))
215 return;
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))
231 return;
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 and Linux; http://crbug.com/462671.
242 #if defined(OS_WIN) || defined(OS_LINUX)
243 #define MAYBE_CrossSiteInfiniteBeforeUnloadSync \
244 DISABLED_CrossSiteInfiniteBeforeUnloadSync
245 #else
246 #define MAYBE_CrossSiteInfiniteBeforeUnloadSync \
247 CrossSiteInfiniteBeforeUnloadSync
248 #endif
249 IN_PROC_BROWSER_TEST_F(UnloadTest, MAYBE_CrossSiteInfiniteBeforeUnloadSync) {
250 // Tests makes no sense in single-process mode since the renderer is hung.
251 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
252 switches::kSingleProcess))
253 return;
255 NavigateToDataURL(INFINITE_BEFORE_UNLOAD_HTML, "infinitebeforeunload");
256 // Must navigate to a non-data URL to trigger cross-site codepath.
257 NavigateToNolistenersFileTwice();
260 // Tests closing the browser on a page with no unload listeners registered.
261 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseNoUnloadListeners) {
262 LoadUrlAndQuitBrowser(NOLISTENERS_HTML, "nolisteners");
265 // Tests closing the browser on a page with an unload listener registered.
266 // Test marked as flaky in http://crbug.com/51698
267 IN_PROC_BROWSER_TEST_F(UnloadTest, DISABLED_BrowserCloseUnload) {
268 LoadUrlAndQuitBrowser(UNLOAD_HTML, "unload");
271 // Tests closing the browser with a beforeunload handler and clicking
272 // OK in the beforeunload confirm dialog.
273 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseBeforeUnloadOK) {
274 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
276 content::WindowedNotificationObserver window_observer(
277 chrome::NOTIFICATION_BROWSER_CLOSED,
278 content::NotificationService::AllSources());
279 chrome::CloseWindow(browser());
280 ClickModalDialogButton(true);
281 window_observer.Wait();
284 // Tests closing the browser with a beforeunload handler and clicking
285 // CANCEL in the beforeunload confirm dialog.
286 // If this test flakes, reopen http://crbug.com/123110
287 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseBeforeUnloadCancel) {
288 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
289 chrome::CloseWindow(browser());
291 // We wait for the title to change after cancelling the popup to ensure that
292 // in-flight IPCs from the renderer reach the browser. Otherwise the browser
293 // won't put up the beforeunload dialog because it's waiting for an ack from
294 // the renderer.
295 base::string16 expected_title = base::ASCIIToUTF16("cancelled");
296 content::TitleWatcher title_watcher(
297 browser()->tab_strip_model()->GetActiveWebContents(), expected_title);
298 ClickModalDialogButton(false);
299 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle());
301 content::WindowedNotificationObserver window_observer(
302 chrome::NOTIFICATION_BROWSER_CLOSED,
303 content::NotificationService::AllSources());
304 chrome::CloseWindow(browser());
305 ClickModalDialogButton(true);
306 window_observer.Wait();
309 // Tests terminating the browser with a beforeunload handler.
310 // Currently only ChromeOS shuts down gracefully.
311 #if defined(OS_CHROMEOS)
312 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserTerminateBeforeUnload) {
313 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
314 EXPECT_EQ(kill(base::GetCurrentProcessHandle(), SIGTERM), 0);
316 #endif
318 // Tests closing the browser and clicking OK in the beforeunload confirm dialog
319 // if an inner frame has the focus.
320 // If this flakes, use http://crbug.com/32615 and http://crbug.com/45675
321 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseWithInnerFocusedFrame) {
322 NavigateToDataURL(INNER_FRAME_WITH_FOCUS_HTML, "innerframewithfocus");
324 content::WindowedNotificationObserver window_observer(
325 chrome::NOTIFICATION_BROWSER_CLOSED,
326 content::NotificationService::AllSources());
327 chrome::CloseWindow(browser());
328 ClickModalDialogButton(true);
329 window_observer.Wait();
332 // Tests closing the browser with a beforeunload handler that takes
333 // two seconds to run.
334 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnload) {
335 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_HTML,
336 "twosecondbeforeunload");
339 // Tests closing the browser on a page with an unload listener registered where
340 // the unload handler has an infinite loop.
341 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseInfiniteUnload) {
342 // Tests makes no sense in single-process mode since the renderer is hung.
343 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
344 switches::kSingleProcess))
345 return;
347 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_HTML, "infiniteunload");
350 // Tests closing the browser with a beforeunload handler that hangs.
351 // If this flakes, use http://crbug.com/78803 and http://crbug.com/86469
352 IN_PROC_BROWSER_TEST_F(UnloadTest, DISABLED_BrowserCloseInfiniteBeforeUnload) {
353 // Tests makes no sense in single-process mode since the renderer is hung.
354 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
355 switches::kSingleProcess))
356 return;
358 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_HTML, "infinitebeforeunload");
361 // Tests closing the browser on a page with an unload listener registered where
362 // the unload handler has an infinite loop followed by an alert.
363 // If this flakes, use http://crbug.com/86469
364 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseInfiniteUnloadAlert) {
365 // Tests makes no sense in single-process mode since the renderer is hung.
366 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
367 switches::kSingleProcess))
368 return;
370 LoadUrlAndQuitBrowser(INFINITE_UNLOAD_ALERT_HTML, "infiniteunloadalert");
373 // Tests closing the browser with a beforeunload handler that hangs then
374 // pops up an alert.
375 // If this flakes, use http://crbug.com/78803 and http://crbug.com/86469.
376 IN_PROC_BROWSER_TEST_F(UnloadTest,
377 DISABLED_BrowserCloseInfiniteBeforeUnloadAlert) {
378 // Tests makes no sense in single-process mode since the renderer is hung.
379 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
380 switches::kSingleProcess))
381 return;
383 LoadUrlAndQuitBrowser(INFINITE_BEFORE_UNLOAD_ALERT_HTML,
384 "infinitebeforeunloadalert");
387 // Tests closing the browser on a page with an unload listener registered where
388 // the unload handler has an 2 second long loop followed by an alert.
389 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseTwoSecondUnloadAlert) {
390 LoadUrlAndQuitBrowser(TWO_SECOND_UNLOAD_ALERT_HTML, "twosecondunloadalert");
393 // Tests closing the browser with a beforeunload handler that takes
394 // two seconds to run then pops up an alert.
395 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseTwoSecondBeforeUnloadAlert) {
396 LoadUrlAndQuitBrowser(TWO_SECOND_BEFORE_UNLOAD_ALERT_HTML,
397 "twosecondbeforeunloadalert");
400 // Tests that if there's a renderer process with two tabs, one of which has an
401 // unload handler, and the other doesn't, the tab that doesn't have an unload
402 // handler can be closed.
403 // If this flakes, see http://crbug.com/45162, http://crbug.com/45281 and
404 // http://crbug.com/86769.
405 IN_PROC_BROWSER_TEST_F(UnloadTest, BrowserCloseTabWhenOtherTabHasListener) {
406 NavigateToDataURL(CLOSE_TAB_WHEN_OTHER_TAB_HAS_LISTENER, "only_one_unload");
408 // Simulate a click to force user_gesture to true; if we don't, the resulting
409 // popup will be constrained, which isn't what we want to test.
411 content::WindowedNotificationObserver observer(
412 chrome::NOTIFICATION_TAB_ADDED,
413 content::NotificationService::AllSources());
414 content::WindowedNotificationObserver load_stop_observer(
415 content::NOTIFICATION_LOAD_STOP,
416 content::NotificationService::AllSources());
417 content::SimulateMouseClick(
418 browser()->tab_strip_model()->GetActiveWebContents(), 0,
419 blink::WebMouseEvent::ButtonLeft);
420 observer.Wait();
421 load_stop_observer.Wait();
422 CheckTitle("popup");
424 content::WebContentsDestroyedWatcher destroyed_watcher(
425 browser()->tab_strip_model()->GetActiveWebContents());
426 chrome::CloseTab(browser());
427 destroyed_watcher.Wait();
429 CheckTitle("only_one_unload");
432 class FastUnloadTest : public UnloadTest {
433 public:
434 void SetUpCommandLine(base::CommandLine* command_line) override {
435 UnloadTest::SetUpCommandLine(command_line);
436 command_line->AppendSwitch(switches::kEnableFastUnload);
439 void SetUpInProcessBrowserTestFixture() override {
440 ASSERT_TRUE(test_server()->Start());
443 void TearDownInProcessBrowserTestFixture() override { test_server()->Stop(); }
445 GURL GetUrl(const std::string& name) {
446 return GURL(test_server()->GetURL(
447 "files/fast_tab_close/" + name + ".html"));
450 void NavigateToPage(const char* name) {
451 ui_test_utils::NavigateToURL(browser(), GetUrl(name));
452 CheckTitle(name);
455 void NavigateToPageInNewTab(const char* name) {
456 ui_test_utils::NavigateToURLWithDisposition(
457 browser(), GetUrl(name), NEW_FOREGROUND_TAB,
458 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
459 CheckTitle(name);
462 std::string GetCookies(const char* name) {
463 content::WebContents* contents =
464 browser()->tab_strip_model()->GetActiveWebContents();
465 return content::GetCookies(contents->GetBrowserContext(), GetUrl(name));
469 class FastTabCloseTabStripModelObserver : public TabStripModelObserver {
470 public:
471 FastTabCloseTabStripModelObserver(TabStripModel* model,
472 base::RunLoop* run_loop)
473 : model_(model),
474 run_loop_(run_loop) {
475 model_->AddObserver(this);
478 ~FastTabCloseTabStripModelObserver() override {
479 model_->RemoveObserver(this);
482 // TabStripModelObserver:
483 void TabDetachedAt(content::WebContents* contents, int index) override {
484 run_loop_->Quit();
487 private:
488 TabStripModel* const model_;
489 base::RunLoop* const run_loop_;
493 // Test that fast-tab-close works when closing a tab with an unload handler
494 // (http://crbug.com/142458).
495 // Flaky on Windows bots (http://crbug.com/267597).
496 #if defined(OS_WIN)
497 #define MAYBE_UnloadHidden \
498 DISABLED_UnloadHidden
499 #else
500 #define MAYBE_UnloadHidden \
501 UnloadHidden
502 #endif
503 IN_PROC_BROWSER_TEST_F(FastUnloadTest, MAYBE_UnloadHidden) {
504 NavigateToPage("no_listeners");
505 NavigateToPageInNewTab("unload_sets_cookie");
506 EXPECT_EQ("", GetCookies("no_listeners"));
508 content::WebContentsDestroyedWatcher destroyed_watcher(
509 browser()->tab_strip_model()->GetActiveWebContents());
512 base::RunLoop run_loop;
513 FastTabCloseTabStripModelObserver observer(
514 browser()->tab_strip_model(), &run_loop);
515 chrome::CloseTab(browser());
516 run_loop.Run();
519 // Check that the browser only has the original tab.
520 CheckTitle("no_listeners");
521 EXPECT_EQ(1, browser()->tab_strip_model()->count());
523 // Wait for the actual destruction.
524 destroyed_watcher.Wait();
526 // Verify that the destruction had the desired effect.
527 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
530 // Test that fast-tab-close does not break a solo tab.
531 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_ClosingLastTabFinishesUnload) {
532 // The unload handler sleeps before setting the cookie to catch cases when
533 // unload handlers are not allowed to run to completion. (For example,
534 // using the detached handler for the tab and then closing the browser.)
535 NavigateToPage("unload_sleep_before_cookie");
536 EXPECT_EQ(1, browser()->tab_strip_model()->count());
537 EXPECT_EQ("", GetCookies("unload_sleep_before_cookie"));
539 content::WindowedNotificationObserver window_observer(
540 chrome::NOTIFICATION_BROWSER_CLOSED,
541 content::NotificationService::AllSources());
542 chrome::CloseTab(browser());
543 window_observer.Wait();
546 // Fails on Mac, Linux, Win7 (http://crbug.com/301173).
547 IN_PROC_BROWSER_TEST_F(FastUnloadTest, DISABLED_ClosingLastTabFinishesUnload) {
548 #if defined(OS_WIN)
549 // Flaky on Win7+ bots (http://crbug.com/267597).
550 if (base::win::GetVersion() >= base::win::VERSION_WIN7)
551 return;
552 #endif
553 // Check for cookie set in unload handler of PRE_ test.
554 NavigateToPage("no_listeners");
555 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
558 // Test that fast-tab-close does not break window close.
559 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_WindowCloseFinishesUnload) {
560 NavigateToPage("no_listeners");
562 // The unload handler sleeps before setting the cookie to catch cases when
563 // unload handlers are not allowed to run to completion. Without the sleep,
564 // the cookie can get set even if the browser does not wait for
565 // the unload handler to finish.
566 NavigateToPageInNewTab("unload_sleep_before_cookie");
567 EXPECT_EQ(2, browser()->tab_strip_model()->count());
568 EXPECT_EQ("", GetCookies("no_listeners"));
570 content::WindowedNotificationObserver window_observer(
571 chrome::NOTIFICATION_BROWSER_CLOSED,
572 content::NotificationService::AllSources());
573 chrome::CloseWindow(browser());
574 window_observer.Wait();
577 // Flaky on Windows bots (http://crbug.com/279267) and fails on Mac / Linux bots
578 // (http://crbug.com/301173).
579 IN_PROC_BROWSER_TEST_F(FastUnloadTest, DISABLED_WindowCloseFinishesUnload) {
580 // Check for cookie set in unload during PRE_ test.
581 NavigateToPage("no_listeners");
582 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners"));
585 // Test that a tab crash during unload does not break window close.
587 // Hits assertion on Linux and Mac:
588 // [FATAL:profile_destroyer.cc(46)] Check failed:
589 // hosts.empty() ||
590 // profile->IsOffTheRecord() ||
591 // content::RenderProcessHost::run_renderer_in_process().
592 // More details: The renderer process host matches the closed, crashed tab.
593 // The |UnloadController| receives |NOTIFICATION_WEB_CONTENTS_DISCONNECTED|
594 // and proceeds with the close.
595 IN_PROC_BROWSER_TEST_F(FastUnloadTest, DISABLED_WindowCloseAfterUnloadCrash) {
596 NavigateToPage("no_listeners");
597 NavigateToPageInNewTab("unload_sets_cookie");
598 content::WebContents* unload_contents =
599 browser()->tab_strip_model()->GetActiveWebContents();
600 EXPECT_EQ("", GetCookies("no_listeners"));
603 base::RunLoop run_loop;
604 FastTabCloseTabStripModelObserver observer(
605 browser()->tab_strip_model(), &run_loop);
606 chrome::CloseTab(browser());
607 run_loop.Run();
610 // Check that the browser only has the original tab.
611 CheckTitle("no_listeners");
612 EXPECT_EQ(1, browser()->tab_strip_model()->count());
614 CrashTab(unload_contents);
616 // Check that the browser only has the original tab.
617 CheckTitle("no_listeners");
618 EXPECT_EQ(1, browser()->tab_strip_model()->count());
620 content::WindowedNotificationObserver window_observer(
621 chrome::NOTIFICATION_BROWSER_CLOSED,
622 content::NotificationService::AllSources());
623 chrome::CloseWindow(browser());
624 window_observer.Wait();
627 // Times out on Windows and Linux.
628 #if defined(OS_WIN) || defined(OS_LINUX)
629 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
630 DISABLED_WindowCloseAfterBeforeUnloadCrash
631 #else
632 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \
633 WindowCloseAfterBeforeUnloadCrash
634 #endif
635 IN_PROC_BROWSER_TEST_F(FastUnloadTest,
636 MAYBE_WindowCloseAfterBeforeUnloadCrash) {
637 // Tests makes no sense in single-process mode since the renderer is hung.
638 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
639 switches::kSingleProcess))
640 return;
642 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload");
643 content::WebContents* beforeunload_contents =
644 browser()->tab_strip_model()->GetActiveWebContents();
646 content::WindowedNotificationObserver window_observer(
647 chrome::NOTIFICATION_BROWSER_CLOSED,
648 content::NotificationService::AllSources());
649 chrome::CloseWindow(browser());
650 CrashTab(beforeunload_contents);
651 window_observer.Wait();
654 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs
655 // and multiple windows.