OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 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 | 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 #if defined(OS_POSIX) | 5 #if defined(OS_POSIX) |
6 #include <signal.h> | 6 #include <signal.h> |
7 #endif | 7 #endif |
8 | 8 |
9 #include "base/command_line.h" | 9 #include "base/command_line.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 394 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
405 | 405 |
406 content::WindowedNotificationObserver tab_close_observer( | 406 content::WindowedNotificationObserver tab_close_observer( |
407 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 407 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
408 content::NotificationService::AllSources()); | 408 content::NotificationService::AllSources()); |
409 chrome::CloseTab(browser()); | 409 chrome::CloseTab(browser()); |
410 tab_close_observer.Wait(); | 410 tab_close_observer.Wait(); |
411 | 411 |
412 CheckTitle("only_one_unload"); | 412 CheckTitle("only_one_unload"); |
413 } | 413 } |
414 | 414 |
415 | |
416 class FastUnloadTest : public UnloadTest { | |
417 public: | |
418 virtual void SetUpInProcessBrowserTestFixture() { | |
419 ASSERT_TRUE(test_server()->Start()); | |
420 } | |
421 | |
422 virtual void TearDownInProcessBrowserTestFixture() { | |
423 test_server()->Stop(); | |
424 } | |
425 | |
426 GURL GetUrl(const std::string& name) { | |
427 return GURL(test_server()->GetURL( | |
428 "files/fast_tab_close/" + name + ".html")); | |
429 } | |
430 | |
431 void NavigateToPage(const char* name) { | |
432 ui_test_utils::NavigateToURL(browser(), GetUrl(name)); | |
433 CheckTitle(name); | |
434 } | |
435 | |
436 void NavigateToPageInNewTab(const char* name) { | |
437 ui_test_utils::NavigateToURLWithDisposition( | |
438 browser(), GetUrl(name), NEW_FOREGROUND_TAB, | |
439 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); | |
440 CheckTitle(name); | |
441 } | |
442 | |
443 std::string GetCookies(const char* name) { | |
444 content::WebContents* contents = | |
445 browser()->tab_strip_model()->GetActiveWebContents(); | |
446 return content::GetCookies(contents->GetBrowserContext(), GetUrl(name)); | |
447 } | |
448 }; | |
449 | |
450 class FastTabCloseTabStripModelObserver : public TabStripModelObserver { | |
451 public: | |
452 FastTabCloseTabStripModelObserver(TabStripModel* model, | |
453 base::RunLoop* run_loop) | |
454 : model_(model), | |
455 run_loop_(run_loop) { | |
456 model_->AddObserver(this); | |
457 } | |
458 | |
459 ~FastTabCloseTabStripModelObserver() { | |
460 model_->RemoveObserver(this); | |
461 } | |
462 | |
463 // TabStripModelObserver: | |
464 virtual void TabDetachedAt(content::WebContents* contents, | |
465 int index) OVERRIDE { | |
466 run_loop_->Quit(); | |
467 } | |
468 | |
469 private: | |
470 TabStripModel* const model_; | |
471 base::RunLoop* const run_loop_; | |
472 }; | |
473 | |
474 | |
475 // Test that fast-tab-close works when closing a tab with an unload handler | |
476 // (http://crbug.com/142458). | |
477 IN_PROC_BROWSER_TEST_F(FastUnloadTest, UnloadHidden) { | |
478 NavigateToPage("no_listeners"); | |
479 NavigateToPageInNewTab("unload_sets_cookie"); | |
480 EXPECT_EQ("", GetCookies("no_listeners")); | |
481 | |
482 { | |
483 base::RunLoop run_loop; | |
484 FastTabCloseTabStripModelObserver observer( | |
485 browser()->tab_strip_model(), &run_loop); | |
486 chrome::CloseTab(browser()); | |
487 run_loop.Run(); | |
488 } | |
489 | |
490 // Check that the browser only has the original tab. | |
491 CheckTitle("no_listeners"); | |
492 EXPECT_EQ(1, browser()->tab_strip_model()->count()); | |
493 | |
494 // Show that the web contents to go away after the was removed. | |
495 // Without unload-detached, this times-out because it happens earlier. | |
496 content::WindowedNotificationObserver contents_destroyed_observer( | |
497 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | |
498 content::NotificationService::AllSources()); | |
499 contents_destroyed_observer.Wait(); | |
500 | |
501 // Browser still has the same tab. | |
502 CheckTitle("no_listeners"); | |
503 EXPECT_EQ(1, browser()->tab_strip_model()->count()); | |
504 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners")); | |
505 } | |
506 | |
507 // Test that fast-tab-close does not break a solo tab. | |
508 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_ClosingLastTabFinishesUnload) { | |
509 // The unload handler sleeps before setting the cookie to catch cases when | |
510 // unload handlers are not allowed to run to completion. (For example, | |
511 // using the detached handler for the tab and then closing the browser.) | |
512 NavigateToPage("unload_sleep_before_cookie"); | |
513 EXPECT_EQ(1, browser()->tab_strip_model()->count()); | |
514 EXPECT_EQ("", GetCookies("unload_sleep_before_cookie")); | |
515 | |
516 content::WindowedNotificationObserver window_observer( | |
517 chrome::NOTIFICATION_BROWSER_CLOSED, | |
518 content::NotificationService::AllSources()); | |
519 chrome::CloseTab(browser()); | |
520 window_observer.Wait(); | |
521 } | |
522 IN_PROC_BROWSER_TEST_F(FastUnloadTest, ClosingLastTabFinishesUnload) { | |
523 // Check for cookie set in unload handler of PRE_ test. | |
524 NavigateToPage("no_listeners"); | |
525 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners")); | |
526 } | |
527 | |
528 // Test that fast-tab-close does not break window close. | |
529 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_WindowCloseFinishesUnload) { | |
530 NavigateToPage("no_listeners"); | |
531 | |
532 // The unload handler sleeps before setting the cookie to catch cases when | |
533 // unload handlers are not allowed to run to completion. Without the sleep, | |
534 // the cookie can get set even if the browser does not wait for | |
535 // the unload handler to finish. | |
536 NavigateToPageInNewTab("unload_sleep_before_cookie"); | |
537 EXPECT_EQ(2, browser()->tab_strip_model()->count()); | |
538 EXPECT_EQ("", GetCookies("no_listeners")); | |
539 | |
540 content::WindowedNotificationObserver window_observer( | |
541 chrome::NOTIFICATION_BROWSER_CLOSED, | |
542 content::NotificationService::AllSources()); | |
543 chrome::CloseWindow(browser()); | |
544 window_observer.Wait(); | |
545 } | |
546 IN_PROC_BROWSER_TEST_F(FastUnloadTest, WindowCloseFinishesUnload) { | |
547 // Check for cookie set in unload during PRE_ test. | |
548 NavigateToPage("no_listeners"); | |
549 EXPECT_EQ("unloaded=ohyeah", GetCookies("no_listeners")); | |
550 } | |
551 | |
552 // Test that a tab crash during unload does not break window close. | |
553 IN_PROC_BROWSER_TEST_F(FastUnloadTest, WindowCloseAfterUnloadCrash) { | |
554 NavigateToPage("no_listeners"); | |
555 NavigateToPageInNewTab("unload_sets_cookie"); | |
556 content::WebContents* unload_contents = | |
557 browser()->tab_strip_model()->GetActiveWebContents(); | |
558 EXPECT_EQ("", GetCookies("no_listeners")); | |
559 | |
560 { | |
561 base::RunLoop run_loop; | |
562 FastTabCloseTabStripModelObserver observer( | |
563 browser()->tab_strip_model(), &run_loop); | |
564 chrome::CloseTab(browser()); | |
565 run_loop.Run(); | |
566 } | |
567 | |
568 // Check that the browser only has the original tab. | |
569 CheckTitle("no_listeners"); | |
570 EXPECT_EQ(1, browser()->tab_strip_model()->count()); | |
571 | |
572 CrashTab(unload_contents); | |
573 | |
574 // Check that the browser only has the original tab. | |
575 CheckTitle("no_listeners"); | |
576 EXPECT_EQ(1, browser()->tab_strip_model()->count()); | |
577 | |
578 content::WindowedNotificationObserver window_observer( | |
579 chrome::NOTIFICATION_BROWSER_CLOSED, | |
580 content::NotificationService::AllSources()); | |
581 chrome::CloseWindow(browser()); | |
582 window_observer.Wait(); | |
583 } | |
584 | |
585 IN_PROC_BROWSER_TEST_F(FastUnloadTest, WindowCloseAfterBeforeUnloadCrash) { | |
586 // Tests makes no sense in single-process mode since the renderer is hung. | |
587 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) | |
588 return; | |
589 | |
590 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload"); | |
591 content::WebContents* beforeunload_contents = | |
592 browser()->tab_strip_model()->GetActiveWebContents(); | |
593 | |
594 content::WindowedNotificationObserver window_observer( | |
595 chrome::NOTIFICATION_BROWSER_CLOSED, | |
596 content::NotificationService::AllSources()); | |
597 chrome::CloseWindow(browser()); | |
598 CrashTab(beforeunload_contents); | |
599 window_observer.Wait(); | |
600 } | |
601 | |
602 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs | 415 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs |
603 // and multiple windows. | 416 // and multiple windows. |
OLD | NEW |