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() OVERRIDE { |
| 419 ASSERT_TRUE(test_server()->Start()); |
| 420 } |
| 421 |
| 422 virtual void TearDownInProcessBrowserTestFixture() OVERRIDE { |
| 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 virtual ~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 // |
| 554 // Hits assertion on Linux and Mac: |
| 555 // [FATAL:profile_destroyer.cc(46)] Check failed: |
| 556 // hosts.empty() || |
| 557 // profile->IsOffTheRecord() || |
| 558 // content::RenderProcessHost::run_renderer_in_process(). |
| 559 // More details: The renderer process host matches the closed, crashed tab. |
| 560 // The |UnloadController| receives |NOTIFICATION_WEB_CONTENTS_DISCONNECTED| |
| 561 // and proceeds with the close. |
| 562 IN_PROC_BROWSER_TEST_F(FastUnloadTest, DISABLED_WindowCloseAfterUnloadCrash) { |
| 563 NavigateToPage("no_listeners"); |
| 564 NavigateToPageInNewTab("unload_sets_cookie"); |
| 565 content::WebContents* unload_contents = |
| 566 browser()->tab_strip_model()->GetActiveWebContents(); |
| 567 EXPECT_EQ("", GetCookies("no_listeners")); |
| 568 |
| 569 { |
| 570 base::RunLoop run_loop; |
| 571 FastTabCloseTabStripModelObserver observer( |
| 572 browser()->tab_strip_model(), &run_loop); |
| 573 chrome::CloseTab(browser()); |
| 574 run_loop.Run(); |
| 575 } |
| 576 |
| 577 // Check that the browser only has the original tab. |
| 578 CheckTitle("no_listeners"); |
| 579 EXPECT_EQ(1, browser()->tab_strip_model()->count()); |
| 580 |
| 581 CrashTab(unload_contents); |
| 582 |
| 583 // Check that the browser only has the original tab. |
| 584 CheckTitle("no_listeners"); |
| 585 EXPECT_EQ(1, browser()->tab_strip_model()->count()); |
| 586 |
| 587 content::WindowedNotificationObserver window_observer( |
| 588 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 589 content::NotificationService::AllSources()); |
| 590 chrome::CloseWindow(browser()); |
| 591 window_observer.Wait(); |
| 592 } |
| 593 |
| 594 // Times out on Windows and Linux. |
| 595 #if defined(OS_WIN) || defined(OS_LINUX) |
| 596 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \ |
| 597 DISABLED_WindowCloseAfterBeforeUnloadCrash |
| 598 #else |
| 599 #define MAYBE_WindowCloseAfterBeforeUnloadCrash \ |
| 600 WindowCloseAfterBeforeUnloadCrash |
| 601 #endif |
| 602 IN_PROC_BROWSER_TEST_F(FastUnloadTest, |
| 603 MAYBE_WindowCloseAfterBeforeUnloadCrash) { |
| 604 // Tests makes no sense in single-process mode since the renderer is hung. |
| 605 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kSingleProcess)) |
| 606 return; |
| 607 |
| 608 NavigateToDataURL(BEFORE_UNLOAD_HTML, "beforeunload"); |
| 609 content::WebContents* beforeunload_contents = |
| 610 browser()->tab_strip_model()->GetActiveWebContents(); |
| 611 |
| 612 content::WindowedNotificationObserver window_observer( |
| 613 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 614 content::NotificationService::AllSources()); |
| 615 chrome::CloseWindow(browser()); |
| 616 CrashTab(beforeunload_contents); |
| 617 window_observer.Wait(); |
| 618 } |
| 619 |
415 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs | 620 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs |
416 // and multiple windows. | 621 // and multiple windows. |
OLD | NEW |