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" |
11 #include "base/process_util.h" | 11 #include "base/process_util.h" |
12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
13 #include "chrome/browser/net/url_request_mock_util.h" | 13 #include "chrome/browser/net/url_request_mock_util.h" |
| 14 #include "chrome/browser/profiles/profile.h" |
14 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" | 15 #include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" |
15 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" | 16 #include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" |
16 #include "chrome/browser/ui/browser.h" | 17 #include "chrome/browser/ui/browser.h" |
17 #include "chrome/browser/ui/browser_commands.h" | 18 #include "chrome/browser/ui/browser_commands.h" |
18 #include "chrome/browser/ui/browser_list.h" | 19 #include "chrome/browser/ui/browser_list.h" |
19 #include "chrome/browser/ui/browser_tabstrip.h" | 20 #include "chrome/browser/ui/browser_tabstrip.h" |
| 21 #include "chrome/browser/ui/tab_contents/tab_contents.h" |
| 22 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
20 #include "chrome/common/chrome_notification_types.h" | 23 #include "chrome/common/chrome_notification_types.h" |
21 #include "chrome/common/chrome_switches.h" | 24 #include "chrome/common/chrome_switches.h" |
22 #include "chrome/test/base/in_process_browser_test.h" | 25 #include "chrome/test/base/in_process_browser_test.h" |
23 #include "chrome/test/base/ui_test_utils.h" | 26 #include "chrome/test/base/ui_test_utils.h" |
24 #include "content/public/browser/browser_thread.h" | 27 #include "content/public/browser/browser_thread.h" |
25 #include "content/public/browser/notification_service.h" | 28 #include "content/public/browser/notification_service.h" |
26 #include "content/public/browser/web_contents.h" | 29 #include "content/public/browser/web_contents.h" |
27 #include "content/public/test/browser_test_utils.h" | 30 #include "content/public/test/browser_test_utils.h" |
28 #include "content/test/net/url_request_mock_http_job.h" | 31 #include "content/test/net/url_request_mock_http_job.h" |
29 #include "net/url_request/url_request_test_util.h" | 32 #include "net/url_request/url_request_test_util.h" |
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
403 | 406 |
404 content::WindowedNotificationObserver tab_close_observer( | 407 content::WindowedNotificationObserver tab_close_observer( |
405 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 408 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
406 content::NotificationService::AllSources()); | 409 content::NotificationService::AllSources()); |
407 chrome::CloseTab(browser()); | 410 chrome::CloseTab(browser()); |
408 tab_close_observer.Wait(); | 411 tab_close_observer.Wait(); |
409 | 412 |
410 CheckTitle("only_one_unload"); | 413 CheckTitle("only_one_unload"); |
411 } | 414 } |
412 | 415 |
| 416 |
| 417 class FastUnloadTest : public UnloadTest { |
| 418 public: |
| 419 virtual void SetUpInProcessBrowserTestFixture() { |
| 420 ASSERT_TRUE(test_server()->Start()); |
| 421 } |
| 422 |
| 423 virtual void TearDownInProcessBrowserTestFixture() { |
| 424 test_server()->Stop(); |
| 425 } |
| 426 |
| 427 GURL GetUrl(const std::string& name) { |
| 428 return GURL(test_server()->GetURL( |
| 429 "files/fast_tab_close/" + name + ".html")); |
| 430 } |
| 431 |
| 432 void NavigateToPage(const char* name) { |
| 433 ui_test_utils::NavigateToURL(browser(), GetUrl(name)); |
| 434 CheckTitle(name); |
| 435 } |
| 436 |
| 437 void NavigateToPageInNewTab(const char* name) { |
| 438 ui_test_utils::NavigateToURLWithDisposition( |
| 439 browser(), GetUrl(name), NEW_FOREGROUND_TAB, |
| 440 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION); |
| 441 CheckTitle(name); |
| 442 } |
| 443 |
| 444 std::string GetActiveTabCookies(const char* name) { |
| 445 TabContents* tab = chrome::GetActiveTabContents(browser()); |
| 446 return content::GetCookies(tab->profile(), 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(TabContents* contents, int index) { |
| 465 run_loop_->Quit(); |
| 466 } |
| 467 |
| 468 private: |
| 469 TabStripModel* const model_; |
| 470 base::RunLoop* const run_loop_; |
| 471 }; |
| 472 |
| 473 |
| 474 // Test that fast-tab-close works when closing a tab (not the last one) with |
| 475 // an unload handler (http://crbug.com/142458). |
| 476 IN_PROC_BROWSER_TEST_F(FastUnloadTest, UnloadHidden) { |
| 477 NavigateToPage("no_listeners"); |
| 478 NavigateToPageInNewTab("unload_sets_cookie"); |
| 479 EXPECT_EQ("", GetActiveTabCookies("no_listeners")); |
| 480 |
| 481 { |
| 482 base::RunLoop run_loop; |
| 483 FastTabCloseTabStripModelObserver observer( |
| 484 browser()->tab_strip_model(), &run_loop); |
| 485 chrome::CloseTab(browser()); |
| 486 run_loop.Run(); |
| 487 } |
| 488 |
| 489 // Check that the browser only has the original tab. |
| 490 CheckTitle("no_listeners"); |
| 491 EXPECT_EQ(1, browser()->tab_count()); |
| 492 |
| 493 // Show that the web contents to go away after the was removed. |
| 494 // Without unload-detached, this times-out because it happens earlier. |
| 495 content::WindowedNotificationObserver contents_destroyed_observer( |
| 496 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| 497 content::NotificationService::AllSources()); |
| 498 contents_destroyed_observer.Wait(); |
| 499 |
| 500 // Browser still has the same tab. |
| 501 CheckTitle("no_listeners"); |
| 502 EXPECT_EQ(1, browser()->tab_count()); |
| 503 EXPECT_EQ("unloaded=ohyeah", GetActiveTabCookies("no_listeners")); |
| 504 } |
| 505 |
| 506 // Test that fast-tab-close does not break a solo tab. |
| 507 // Fast window close feature request: http://crbug.com/156896 |
| 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_count()); |
| 514 EXPECT_EQ("", GetActiveTabCookies("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", GetActiveTabCookies("no_listeners")); |
| 526 } |
| 527 |
| 528 // Test that fast-tab-close does not break window close. |
| 529 // Fast window close feature request: http://crbug.com/156896 |
| 530 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_WindowCloseFinishesUnload) { |
| 531 NavigateToPage("no_listeners"); |
| 532 |
| 533 // The unload handler sleeps before setting the cookie to catch cases when |
| 534 // unload handlers are not allowed to run to completion. Without the sleep, |
| 535 // the cookie can get set even if the browser does not wait for |
| 536 // the unload handler to finish. |
| 537 NavigateToPageInNewTab("unload_sleep_before_cookie"); |
| 538 EXPECT_EQ(2, browser()->tab_count()); |
| 539 EXPECT_EQ("", GetActiveTabCookies("no_listeners")); |
| 540 |
| 541 content::WindowedNotificationObserver window_observer( |
| 542 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 543 content::NotificationService::AllSources()); |
| 544 chrome::CloseWindow(browser()); |
| 545 window_observer.Wait(); |
| 546 } |
| 547 IN_PROC_BROWSER_TEST_F(FastUnloadTest, WindowCloseFinishesUnload) { |
| 548 // Check for cookie set in unload during PRE_ test. |
| 549 NavigateToPage("no_listeners"); |
| 550 EXPECT_EQ("unloaded=ohyeah", GetActiveTabCookies("no_listeners")); |
| 551 } |
| 552 |
| 553 |
413 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs | 554 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs |
414 // and multiple windows. | 555 // and multiple windows. |
OLD | NEW |