| 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 |