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 372 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
402 | 405 |
403 content::WindowedNotificationObserver tab_close_observer( | 406 content::WindowedNotificationObserver tab_close_observer( |
404 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, | 407 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
405 content::NotificationService::AllSources()); | 408 content::NotificationService::AllSources()); |
406 chrome::CloseTab(browser()); | 409 chrome::CloseTab(browser()); |
407 tab_close_observer.Wait(); | 410 tab_close_observer.Wait(); |
408 | 411 |
409 CheckTitle("only_one_unload"); | 412 CheckTitle("only_one_unload"); |
410 } | 413 } |
411 | 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 GetActiveTabCookies(const char* name) { |
| 444 TabContents* tab = chrome::GetActiveTabContents(browser()); |
| 445 return content::GetCookies(tab->profile(), GetUrl(name)); |
| 446 } |
| 447 }; |
| 448 |
| 449 class FastTabCloseTabStripModelObserver : public TabStripModelObserver { |
| 450 public: |
| 451 FastTabCloseTabStripModelObserver(TabStripModel* model, |
| 452 base::RunLoop* run_loop) |
| 453 : model_(model), |
| 454 run_loop_(run_loop) { |
| 455 model_->AddObserver(this); |
| 456 } |
| 457 |
| 458 ~FastTabCloseTabStripModelObserver() { |
| 459 model_->RemoveObserver(this); |
| 460 } |
| 461 |
| 462 // TabStripModelObserver: |
| 463 virtual void TabDetachedAt(TabContents* contents, int index) { |
| 464 run_loop_->Quit(); |
| 465 } |
| 466 |
| 467 private: |
| 468 TabStripModel* const model_; |
| 469 base::RunLoop* const run_loop_; |
| 470 }; |
| 471 |
| 472 |
| 473 // Test that fast-tab-close works when closing a tab (not the last one) with |
| 474 // an unload handler (http://crbug.com/142458). |
| 475 IN_PROC_BROWSER_TEST_F(FastUnloadTest, UnloadHidden) { |
| 476 NavigateToPage("no_listeners"); |
| 477 NavigateToPageInNewTab("unload_sets_cookie"); |
| 478 EXPECT_EQ("", GetActiveTabCookies("no_listeners")); |
| 479 |
| 480 { |
| 481 base::RunLoop run_loop; |
| 482 FastTabCloseTabStripModelObserver observer( |
| 483 browser()->tab_strip_model(), &run_loop); |
| 484 chrome::CloseTab(browser()); |
| 485 run_loop.Run(); |
| 486 } |
| 487 |
| 488 // Check that the browser only has the original tab. |
| 489 CheckTitle("no_listeners"); |
| 490 EXPECT_EQ(1, browser()->tab_count()); |
| 491 |
| 492 // Show that the web contents to go away after the was removed. |
| 493 // Without unload-detached, this times-out because it happens earlier. |
| 494 content::WindowedNotificationObserver contents_destroyed_observer( |
| 495 content::NOTIFICATION_WEB_CONTENTS_DESTROYED, |
| 496 content::NotificationService::AllSources()); |
| 497 contents_destroyed_observer.Wait(); |
| 498 |
| 499 // Browser still has the same tab. |
| 500 CheckTitle("no_listeners"); |
| 501 EXPECT_EQ(1, browser()->tab_count()); |
| 502 EXPECT_EQ("unloaded=ohyeah", GetActiveTabCookies("no_listeners")); |
| 503 } |
| 504 |
| 505 // Test that fast-tab-close does not break a solo tab. |
| 506 // Fast window close feature request: http://crbug.com/156896 |
| 507 IN_PROC_BROWSER_TEST_F(FastUnloadTest, PRE_ClosingLastTabFinishesUnload) { |
| 508 // The unload handler sleeps before setting the cookie to catch cases when |
| 509 // unload handlers are not allowed to run to completion. (For example, |
| 510 // using the detached handler for the tab and then closing the browser.) |
| 511 NavigateToPage("unload_sleep_before_cookie"); |
| 512 EXPECT_EQ(1, browser()->tab_count()); |
| 513 EXPECT_EQ("", GetActiveTabCookies("unload_sleep_before_cookie")); |
| 514 |
| 515 content::WindowedNotificationObserver window_observer( |
| 516 chrome::NOTIFICATION_BROWSER_CLOSED, |
| 517 content::NotificationService::AllSources()); |
| 518 chrome::CloseTab(browser()); |
| 519 window_observer.Wait(); |
| 520 } |
| 521 IN_PROC_BROWSER_TEST_F(FastUnloadTest, ClosingLastTabFinishesUnload) { |
| 522 // Check for cookie set in unload handler of PRE_ test. |
| 523 NavigateToPage("no_listeners"); |
| 524 EXPECT_EQ("unloaded=ohyeah", GetActiveTabCookies("no_listeners")); |
| 525 } |
| 526 |
| 527 // Test that fast-tab-close does not break window close. |
| 528 // Fast window close feature request: http://crbug.com/156896 |
| 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_count()); |
| 538 EXPECT_EQ("", GetActiveTabCookies("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", GetActiveTabCookies("no_listeners")); |
| 550 } |
| 551 |
| 552 |
412 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs | 553 // TODO(ojan): Add tests for unload/beforeunload that have multiple tabs |
413 // and multiple windows. | 554 // and multiple windows. |
OLD | NEW |