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