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 3// found in the LICENSE file. 4 5#include <string> 6 7#include "base/bind.h" 8#include "base/command_line.h" 9#include "base/compiler_specific.h" 10#include "base/files/file_path.h" 11#include "base/prefs/pref_service.h" 12#include "base/strings/utf_string_conversions.h" 13#include "base/sys_info.h" 14#include "chrome/app/chrome_command_ids.h" 15#include "chrome/browser/chrome_content_browser_client.h" 16#include "chrome/browser/chrome_notification_types.h" 17#include "chrome/browser/command_updater.h" 18#include "chrome/browser/content_settings/host_content_settings_map.h" 19#include "chrome/browser/defaults.h" 20#include "chrome/browser/extensions/extension_browsertest.h" 21#include "chrome/browser/extensions/extension_service.h" 22#include "chrome/browser/extensions/extension_system.h" 23#include "chrome/browser/extensions/tab_helper.h" 24#include "chrome/browser/first_run/first_run.h" 25#include "chrome/browser/prefs/incognito_mode_prefs.h" 26#include "chrome/browser/profiles/profile.h" 27#include "chrome/browser/profiles/profile_manager.h" 28#include "chrome/browser/sessions/session_backend.h" 29#include "chrome/browser/sessions/session_service_factory.h" 30#include "chrome/browser/translate/translate_tab_helper.h" 31#include "chrome/browser/ui/app_modal_dialogs/app_modal_dialog.h" 32#include "chrome/browser/ui/app_modal_dialogs/javascript_app_modal_dialog.h" 33#include "chrome/browser/ui/app_modal_dialogs/native_app_modal_dialog.h" 34#include "chrome/browser/ui/browser.h" 35#include "chrome/browser/ui/browser_command_controller.h" 36#include "chrome/browser/ui/browser_commands.h" 37#include "chrome/browser/ui/browser_finder.h" 38#include "chrome/browser/ui/browser_iterator.h" 39#include "chrome/browser/ui/browser_navigator.h" 40#include "chrome/browser/ui/browser_tabstrip.h" 41#include "chrome/browser/ui/browser_ui_prefs.h" 42#include "chrome/browser/ui/browser_window.h" 43#include "chrome/browser/ui/extensions/application_launch.h" 44#include "chrome/browser/ui/host_desktop.h" 45#include "chrome/browser/ui/startup/startup_browser_creator.h" 46#include "chrome/browser/ui/startup/startup_browser_creator_impl.h" 47#include "chrome/browser/ui/tabs/pinned_tab_codec.h" 48#include "chrome/browser/ui/tabs/tab_strip_model.h" 49#include "chrome/common/chrome_switches.h" 50#include "chrome/common/extensions/extension.h" 51#include "chrome/common/extensions/manifest_handlers/app_launch_info.h" 52#include "chrome/common/translate/language_detection_details.h" 53#include "chrome/common/url_constants.h" 54#include "chrome/test/base/in_process_browser_test.h" 55#include "chrome/test/base/test_switches.h" 56#include "chrome/test/base/ui_test_utils.h" 57#include "content/public/browser/favicon_status.h" 58#include "content/public/browser/host_zoom_map.h" 59#include "content/public/browser/interstitial_page.h" 60#include "content/public/browser/interstitial_page_delegate.h" 61#include "content/public/browser/navigation_entry.h" 62#include "content/public/browser/notification_service.h" 63#include "content/public/browser/render_process_host.h" 64#include "content/public/browser/render_view_host.h" 65#include "content/public/browser/render_widget_host_view.h" 66#include "content/public/browser/resource_context.h" 67#include "content/public/browser/web_contents.h" 68#include "content/public/browser/web_contents_observer.h" 69#include "content/public/common/page_transition_types.h" 70#include "content/public/common/renderer_preferences.h" 71#include "content/public/common/url_constants.h" 72#include "content/public/test/browser_test_utils.h" 73#include "content/public/test/test_navigation_observer.h" 74#include "grit/chromium_strings.h" 75#include "grit/generated_resources.h" 76#include "net/dns/mock_host_resolver.h" 77#include "net/test/spawned_test_server/spawned_test_server.h" 78#include "ui/base/l10n/l10n_util.h" 79 80#if defined(OS_MACOSX) 81#include "base/mac/mac_util.h" 82#include "base/mac/scoped_nsautorelease_pool.h" 83#include "chrome/browser/ui/cocoa/run_loop_testing.h" 84#endif 85 86#if defined(OS_WIN) 87#include "base/i18n/rtl.h" 88#include "chrome/browser/browser_process.h" 89#endif 90 91using content::InterstitialPage; 92using content::HostZoomMap; 93using content::NavigationController; 94using content::NavigationEntry; 95using content::OpenURLParams; 96using content::Referrer; 97using content::WebContents; 98using content::WebContentsObserver; 99using extensions::Extension; 100 101namespace { 102 103const char* kBeforeUnloadHTML = 104 "<html><head><title>beforeunload</title></head><body>" 105 "<script>window.onbeforeunload=function(e){return 'foo'}</script>" 106 "</body></html>"; 107 108const char* kOpenNewBeforeUnloadPage = 109 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};"; 110 111const base::FilePath::CharType* kBeforeUnloadFile = 112 FILE_PATH_LITERAL("beforeunload.html"); 113 114const base::FilePath::CharType* kTitle1File = FILE_PATH_LITERAL("title1.html"); 115const base::FilePath::CharType* kTitle2File = FILE_PATH_LITERAL("title2.html"); 116 117const base::FilePath::CharType kDocRoot[] = 118 FILE_PATH_LITERAL("chrome/test/data"); 119 120// Given a page title, returns the expected window caption string. 121string16 WindowCaptionFromPageTitle(const string16& page_title) { 122#if defined(OS_MACOSX) || defined(OS_CHROMEOS) 123 // On Mac or ChromeOS, we don't want to suffix the page title with 124 // the application name. 125 if (page_title.empty()) 126 return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED); 127 return page_title; 128#else 129 if (page_title.empty()) 130 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME); 131 132 return l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT, 133 page_title); 134#endif 135} 136 137// Returns the number of active RenderProcessHosts. 138int CountRenderProcessHosts() { 139 int result = 0; 140 for (content::RenderProcessHost::iterator i( 141 content::RenderProcessHost::AllHostsIterator()); 142 !i.IsAtEnd(); i.Advance()) 143 ++result; 144 return result; 145} 146 147class MockTabStripModelObserver : public TabStripModelObserver { 148 public: 149 MockTabStripModelObserver() : closing_count_(0) {} 150 151 virtual void TabClosingAt(TabStripModel* tab_strip_model, 152 WebContents* contents, 153 int index) OVERRIDE { 154 ++closing_count_; 155 } 156 157 int closing_count() const { return closing_count_; } 158 159 private: 160 int closing_count_; 161 162 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver); 163}; 164 165class InterstitialObserver : public content::WebContentsObserver { 166 public: 167 InterstitialObserver(content::WebContents* web_contents, 168 const base::Closure& attach_callback, 169 const base::Closure& detach_callback) 170 : WebContentsObserver(web_contents), 171 attach_callback_(attach_callback), 172 detach_callback_(detach_callback) { 173 } 174 175 virtual void DidAttachInterstitialPage() OVERRIDE { 176 attach_callback_.Run(); 177 } 178 179 virtual void DidDetachInterstitialPage() OVERRIDE { 180 detach_callback_.Run(); 181 } 182 183 private: 184 base::Closure attach_callback_; 185 base::Closure detach_callback_; 186 187 DISALLOW_COPY_AND_ASSIGN(InterstitialObserver); 188}; 189 190// Causes the browser to swap processes on a redirect to an HTTPS URL. 191class TransferHttpsRedirectsContentBrowserClient 192 : public chrome::ChromeContentBrowserClient { 193 public: 194 virtual bool ShouldSwapProcessesForRedirect( 195 content::ResourceContext* resource_context, 196 const GURL& current_url, 197 const GURL& new_url) OVERRIDE { 198 return new_url.SchemeIs(chrome::kHttpsScheme); 199 } 200}; 201 202// Used by CloseWithAppMenuOpen. Invokes CloseWindow on the supplied browser. 203void CloseWindowCallback(Browser* browser) { 204 chrome::CloseWindow(browser); 205} 206 207// Used by CloseWithAppMenuOpen. Posts a CloseWindowCallback and shows the app 208// menu. 209void RunCloseWithAppMenuCallback(Browser* browser) { 210 // ShowAppMenu is modal under views. Schedule a task that closes the window. 211 base::MessageLoop::current()->PostTask( 212 FROM_HERE, base::Bind(&CloseWindowCallback, browser)); 213 chrome::ShowAppMenu(browser); 214} 215 216// Displays "INTERSTITIAL" while the interstitial is attached. 217// (InterstitialPage can be used in a test directly, but there would be no way 218// to visually tell if it is showing or not.) 219class TestInterstitialPage : public content::InterstitialPageDelegate { 220 public: 221 TestInterstitialPage(WebContents* tab, bool new_navigation, const GURL& url) { 222 interstitial_page_ = InterstitialPage::Create( 223 tab, new_navigation, url , this); 224 interstitial_page_->Show(); 225 } 226 virtual ~TestInterstitialPage() { } 227 void Proceed() { 228 interstitial_page_->Proceed(); 229 } 230 231 virtual std::string GetHTMLContents() OVERRIDE { 232 return "<h1>INTERSTITIAL</h1>"; 233 } 234 235 private: 236 InterstitialPage* interstitial_page_; // Owns us. 237}; 238 239} // namespace 240 241class BrowserTest : public ExtensionBrowserTest { 242 protected: 243 // In RTL locales wrap the page title with RTL embedding characters so that it 244 // matches the value returned by GetWindowTitle(). 245 string16 LocaleWindowCaptionFromPageTitle(const string16& expected_title) { 246 string16 page_title = WindowCaptionFromPageTitle(expected_title); 247#if defined(OS_WIN) 248 std::string locale = g_browser_process->GetApplicationLocale(); 249 if (base::i18n::GetTextDirectionForLocale(locale.c_str()) == 250 base::i18n::RIGHT_TO_LEFT) { 251 base::i18n::WrapStringWithLTRFormatting(&page_title); 252 } 253 254 return page_title; 255#else 256 // Do we need to use the above code on POSIX as well? 257 return page_title; 258#endif 259 } 260 261 // Returns the app extension aptly named "App Test". 262 const Extension* GetExtension() { 263 const ExtensionSet* extensions = extensions::ExtensionSystem::Get( 264 browser()->profile())->extension_service()->extensions(); 265 for (ExtensionSet::const_iterator it = extensions->begin(); 266 it != extensions->end(); ++it) { 267 if ((*it)->name() == "App Test") 268 return it->get(); 269 } 270 NOTREACHED(); 271 return NULL; 272 } 273}; 274 275// Launch the app on a page with no title, check that the app title was set 276// correctly. 277IN_PROC_BROWSER_TEST_F(BrowserTest, NoTitle) { 278#if defined(OS_WIN) && defined(USE_ASH) 279 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 280 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 281 return; 282#endif 283 284 ui_test_utils::NavigateToURL( 285 browser(), ui_test_utils::GetTestUrl( 286 base::FilePath(base::FilePath::kCurrentDirectory), 287 base::FilePath(kTitle1File))); 288 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")), 289 browser()->GetWindowTitleForCurrentTab()); 290 string16 tab_title; 291 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title)); 292 EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title); 293} 294 295// Launch the app, navigate to a page with a title, check that the app title 296// was set correctly. 297IN_PROC_BROWSER_TEST_F(BrowserTest, Title) { 298#if defined(OS_WIN) && defined(USE_ASH) 299 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 300 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 301 return; 302#endif 303 304 ui_test_utils::NavigateToURL( 305 browser(), ui_test_utils::GetTestUrl( 306 base::FilePath(base::FilePath::kCurrentDirectory), 307 base::FilePath(kTitle2File))); 308 const string16 test_title(ASCIIToUTF16("Title Of Awesomeness")); 309 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title), 310 browser()->GetWindowTitleForCurrentTab()); 311 string16 tab_title; 312 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title)); 313 EXPECT_EQ(test_title, tab_title); 314} 315 316IN_PROC_BROWSER_TEST_F(BrowserTest, JavascriptAlertActivatesTab) { 317 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 318 base::FilePath::kCurrentDirectory), base::FilePath(kTitle1File))); 319 ui_test_utils::NavigateToURL(browser(), url); 320 AddTabAtIndex(0, url, content::PAGE_TRANSITION_TYPED); 321 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 322 EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); 323 WebContents* second_tab = browser()->tab_strip_model()->GetWebContentsAt(1); 324 ASSERT_TRUE(second_tab); 325 second_tab->GetRenderViewHost()->ExecuteJavascriptInWebFrame( 326 string16(), 327 ASCIIToUTF16("alert('Activate!');")); 328 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 329 alert->CloseModalDialog(); 330 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 331 EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); 332} 333 334 335#if defined(OS_WIN) && !defined(NDEBUG) 336// http://crbug.com/114859. Times out frequently on Windows. 337#define MAYBE_ThirtyFourTabs DISABLED_ThirtyFourTabs 338#else 339#define MAYBE_ThirtyFourTabs ThirtyFourTabs 340#endif 341 342// Create 34 tabs and verify that a lot of processes have been created. The 343// exact number of processes depends on the amount of memory. Previously we 344// had a hard limit of 31 processes and this test is mainly directed at 345// verifying that we don't crash when we pass this limit. 346// Warning: this test can take >30 seconds when running on a slow (low 347// memory?) Mac builder. 348IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_ThirtyFourTabs) { 349 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 350 base::FilePath::kCurrentDirectory), base::FilePath(kTitle2File))); 351 352 // There is one initial tab. 353 const int kTabCount = 34; 354 for (int ix = 0; ix != (kTabCount - 1); ++ix) { 355 chrome::AddSelectedTabWithURL(browser(), url, 356 content::PAGE_TRANSITION_TYPED); 357 } 358 EXPECT_EQ(kTabCount, browser()->tab_strip_model()->count()); 359 360 // See GetMaxRendererProcessCount() in 361 // content/browser/renderer_host/render_process_host_impl.cc 362 // for the algorithm to decide how many processes to create. 363 const int kExpectedProcessCount = 364#if defined(ARCH_CPU_64_BITS) 365 17; 366#else 367 25; 368#endif 369 if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) { 370 EXPECT_GE(CountRenderProcessHosts(), kExpectedProcessCount); 371 } else { 372 EXPECT_LT(CountRenderProcessHosts(), kExpectedProcessCount); 373 } 374} 375 376// Test for crbug.com/22004. Reloading a page with a before unload handler and 377// then canceling the dialog should not leave the throbber spinning. 378IN_PROC_BROWSER_TEST_F(BrowserTest, ReloadThenCancelBeforeUnload) { 379 GURL url(std::string("data:text/html,") + kBeforeUnloadHTML); 380 ui_test_utils::NavigateToURL(browser(), url); 381 382 // Navigate to another page, but click cancel in the dialog. Make sure that 383 // the throbber stops spinning. 384 chrome::Reload(browser(), CURRENT_TAB); 385 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 386 alert->CloseModalDialog(); 387 EXPECT_FALSE( 388 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading()); 389 390 // Clear the beforeunload handler so the test can easily exit. 391 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()-> 392 ExecuteJavascriptInWebFrame(string16(), 393 ASCIIToUTF16("onbeforeunload=null;")); 394} 395 396// Ensure that a transferred cross-process navigation does not generate 397// DidStopLoading events until the navigation commits. If it did, then 398// ui_test_utils::NavigateToURL would proceed before the URL had committed. 399// http://crbug.com/243957. 400IN_PROC_BROWSER_TEST_F(BrowserTest, NoStopDuringTransferUntilCommit) { 401 // Create HTTP and HTTPS servers for a cross-site transition. 402 ASSERT_TRUE(test_server()->Start()); 403 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 404 net::SpawnedTestServer::kLocalhost, 405 base::FilePath(kDocRoot)); 406 ASSERT_TRUE(https_test_server.Start()); 407 408 // Temporarily replace ContentBrowserClient with one that will cause a 409 // process swap on all redirects to HTTPS URLs. 410 TransferHttpsRedirectsContentBrowserClient new_client; 411 content::ContentBrowserClient* old_client = 412 SetBrowserClientForTesting(&new_client); 413 414 GURL init_url(test_server()->GetURL("files/title1.html")); 415 ui_test_utils::NavigateToURL(browser(), init_url); 416 417 // Navigate to a same-site page that redirects, causing a transfer. 418 GURL dest_url(https_test_server.GetURL("files/title2.html")); 419 GURL redirect_url(test_server()->GetURL("server-redirect?" + 420 dest_url.spec())); 421 ui_test_utils::NavigateToURL(browser(), redirect_url); 422 423 // We should immediately see the new committed entry. 424 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 425 EXPECT_FALSE(contents->GetController().GetPendingEntry()); 426 EXPECT_EQ(dest_url, 427 contents->GetController().GetLastCommittedEntry()->GetURL()); 428 429 // Restore previous browser client. 430 SetBrowserClientForTesting(old_client); 431} 432 433// Tests that a cross-process redirect will only cause the beforeunload 434// handler to run once. 435IN_PROC_BROWSER_TEST_F(BrowserTest, SingleBeforeUnloadAfterRedirect) { 436 // Create HTTP and HTTPS servers for a cross-site transition. 437 ASSERT_TRUE(test_server()->Start()); 438 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 439 net::SpawnedTestServer::kLocalhost, 440 base::FilePath(kDocRoot)); 441 ASSERT_TRUE(https_test_server.Start()); 442 443 // Temporarily replace ContentBrowserClient with one that will cause a 444 // process swap on all redirects to HTTPS URLs. 445 TransferHttpsRedirectsContentBrowserClient new_client; 446 content::ContentBrowserClient* old_client = 447 SetBrowserClientForTesting(&new_client); 448 449 // Navigate to a page with a beforeunload handler. 450 GURL url(test_server()->GetURL("files/beforeunload.html")); 451 ui_test_utils::NavigateToURL(browser(), url); 452 453 // Navigate to a URL that redirects to another process and approve the 454 // beforeunload dialog that pops up. 455 content::WindowedNotificationObserver nav_observer( 456 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 457 content::NotificationService::AllSources()); 458 GURL https_url(https_test_server.GetURL("files/title1.html")); 459 GURL redirect_url(test_server()->GetURL("server-redirect?" + 460 https_url.spec())); 461 browser()->OpenURL(OpenURLParams(redirect_url, Referrer(), CURRENT_TAB, 462 content::PAGE_TRANSITION_TYPED, false)); 463 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 464 EXPECT_TRUE( 465 static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog()); 466 alert->native_dialog()->AcceptAppModalDialog(); 467 nav_observer.Wait(); 468 469 // Restore previous browser client. 470 SetBrowserClientForTesting(old_client); 471} 472 473// Test for crbug.com/80401. Canceling a before unload dialog should reset 474// the URL to the previous page's URL. 475IN_PROC_BROWSER_TEST_F(BrowserTest, CancelBeforeUnloadResetsURL) { 476 GURL url(ui_test_utils::GetTestUrl(base::FilePath( 477 base::FilePath::kCurrentDirectory), base::FilePath(kBeforeUnloadFile))); 478 ui_test_utils::NavigateToURL(browser(), url); 479 480 // Navigate to a page that triggers a cross-site transition. 481 ASSERT_TRUE(test_server()->Start()); 482 GURL url2(test_server()->GetURL("files/title1.html")); 483 browser()->OpenURL(OpenURLParams( 484 url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 485 486 content::WindowedNotificationObserver host_destroyed_observer( 487 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED, 488 content::NotificationService::AllSources()); 489 490 // Cancel the dialog. 491 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 492 alert->CloseModalDialog(); 493 EXPECT_FALSE( 494 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading()); 495 496 // Verify there are no pending history items after the dialog is cancelled. 497 // (see crbug.com/93858) 498 NavigationEntry* entry = browser()->tab_strip_model()-> 499 GetActiveWebContents()->GetController().GetPendingEntry(); 500 EXPECT_EQ(NULL, entry); 501 502 // Wait for the ShouldClose_ACK to arrive. We can detect it by waiting for 503 // the pending RVH to be destroyed. 504 host_destroyed_observer.Wait(); 505 EXPECT_EQ(url, browser()->toolbar_model()->GetURL()); 506 507 // Clear the beforeunload handler so the test can easily exit. 508 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()-> 509 ExecuteJavascriptInWebFrame(string16(), 510 ASCIIToUTF16("onbeforeunload=null;")); 511} 512 513// Crashy on mac. http://crbug.com/38522 Crashy on win too (after 3 years). 514#if defined(OS_MACOSX) || defined(OS_WIN) 515#define MAYBE_SingleBeforeUnloadAfterWindowClose \ 516 DISABLED_SingleBeforeUnloadAfterWindowClose 517#else 518#define MAYBE_SingleBeforeUnloadAfterWindowClose \ 519 SingleBeforeUnloadAfterWindowClose 520#endif 521 522// Test for crbug.com/11647. A page closed with window.close() should not have 523// two beforeunload dialogs shown. 524IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_SingleBeforeUnloadAfterWindowClose) { 525 browser()->tab_strip_model()->GetActiveWebContents()->GetRenderViewHost()-> 526 ExecuteJavascriptInWebFrame(string16(), 527 ASCIIToUTF16(kOpenNewBeforeUnloadPage)); 528 529 // Close the new window with JavaScript, which should show a single 530 // beforeunload dialog. Then show another alert, to make it easy to verify 531 // that a second beforeunload dialog isn't shown. 532 browser()->tab_strip_model()->GetWebContentsAt(0)->GetRenderViewHost()-> 533 ExecuteJavascriptInWebFrame(string16(), 534 ASCIIToUTF16("w.close(); alert('bar');")); 535 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 536 alert->native_dialog()->AcceptAppModalDialog(); 537 538 alert = ui_test_utils::WaitForAppModalDialog(); 539 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)-> 540 is_before_unload_dialog()); 541 alert->native_dialog()->AcceptAppModalDialog(); 542} 543 544// BrowserTest.BeforeUnloadVsBeforeReload times out on Windows. 545// http://crbug.com/130411 546#if defined(OS_WIN) 547#define MAYBE_BeforeUnloadVsBeforeReload DISABLED_BeforeUnloadVsBeforeReload 548#else 549#define MAYBE_BeforeUnloadVsBeforeReload BeforeUnloadVsBeforeReload 550#endif 551 552// Test that when a page has an onunload handler, reloading a page shows a 553// different dialog than navigating to a different page. 554IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_BeforeUnloadVsBeforeReload) { 555 GURL url(std::string("data:text/html,") + kBeforeUnloadHTML); 556 ui_test_utils::NavigateToURL(browser(), url); 557 558 // Reload the page, and check that we get a "before reload" dialog. 559 chrome::Reload(browser(), CURRENT_TAB); 560 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 561 EXPECT_TRUE(static_cast<JavaScriptAppModalDialog*>(alert)->is_reload()); 562 563 // Cancel the reload. 564 alert->native_dialog()->CancelAppModalDialog(); 565 566 // Navigate to another url, and check that we get a "before unload" dialog. 567 GURL url2(std::string("about:blank")); 568 browser()->OpenURL(OpenURLParams( 569 url2, Referrer(), CURRENT_TAB, content::PAGE_TRANSITION_TYPED, false)); 570 571 alert = ui_test_utils::WaitForAppModalDialog(); 572 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog*>(alert)->is_reload()); 573 574 // Accept the navigation so we end up on a page without a beforeunload hook. 575 alert->native_dialog()->AcceptAppModalDialog(); 576} 577 578// BeforeUnloadAtQuitWithTwoWindows is a regression test for 579// http://crbug.com/11842. It opens two windows, one of which has a 580// beforeunload handler and attempts to exit cleanly. 581class BeforeUnloadAtQuitWithTwoWindows : public InProcessBrowserTest { 582 public: 583 // This test is for testing a specific shutdown behavior. This mimics what 584 // happens in InProcessBrowserTest::RunTestOnMainThread and QuitBrowsers, but 585 // ensures that it happens through the single IDC_EXIT of the test. 586 virtual void CleanUpOnMainThread() OVERRIDE { 587 // Cycle both the MessageLoop and the Cocoa runloop twice to flush out any 588 // Chrome work that generates Cocoa work. Do this twice since there are two 589 // Browsers that must be closed. 590 CycleRunLoops(); 591 CycleRunLoops(); 592 593 // Run the application event loop to completion, which will cycle the 594 // native MessagePump on all platforms. 595 base::MessageLoop::current()->PostTask(FROM_HERE, 596 base::MessageLoop::QuitClosure()); 597 base::MessageLoop::current()->Run(); 598 599 // Take care of any remaining Cocoa work. 600 CycleRunLoops(); 601 602 // At this point, quit should be for real now. 603 ASSERT_EQ(0u, chrome::GetTotalBrowserCount()); 604 } 605 606 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run 607 // loop. It also drains the NSAutoreleasePool. 608 void CycleRunLoops() { 609 content::RunAllPendingInMessageLoop(); 610#if defined(OS_MACOSX) 611 chrome::testing::NSRunLoopRunAllPending(); 612 AutoreleasePool()->Recycle(); 613#endif 614 } 615}; 616 617// Disabled, http://crbug.com/159214 . 618IN_PROC_BROWSER_TEST_F(BeforeUnloadAtQuitWithTwoWindows, 619 DISABLED_IfThisTestTimesOutItIndicatesFAILURE) { 620 // In the first browser, set up a page that has a beforeunload handler. 621 GURL url(std::string("data:text/html,") + kBeforeUnloadHTML); 622 ui_test_utils::NavigateToURL(browser(), url); 623 624 // Open a second browser window at about:blank. 625 ui_test_utils::BrowserAddedObserver browser_added_observer; 626 chrome::NewEmptyWindow(browser()->profile(), chrome::GetActiveDesktop()); 627 Browser* second_window = browser_added_observer.WaitForSingleNewBrowser(); 628 ui_test_utils::NavigateToURL(second_window, GURL("about:blank")); 629 630 // Tell the application to quit. IDC_EXIT calls AttemptUserExit, which on 631 // everything but ChromeOS allows unload handlers to block exit. On that 632 // platform, though, it exits unconditionally. See the comment and bug ID 633 // in AttemptUserExit() in application_lifetime.cc. 634#if defined(OS_CHROMEOS) 635 chrome::AttemptExit(); 636#else 637 chrome::ExecuteCommand(second_window, IDC_EXIT); 638#endif 639 640 // The beforeunload handler will run at exit, ensure it does, and then accept 641 // it to allow shutdown to proceed. 642 AppModalDialog* alert = ui_test_utils::WaitForAppModalDialog(); 643 ASSERT_TRUE(alert); 644 EXPECT_TRUE( 645 static_cast<JavaScriptAppModalDialog*>(alert)->is_before_unload_dialog()); 646 alert->native_dialog()->AcceptAppModalDialog(); 647 648 // But wait there's more! If this test times out, it likely means that the 649 // browser has not been able to quit correctly, indicating there's a 650 // regression of the bug noted above. 651} 652 653// Test that scripts can fork a new renderer process for a cross-site popup, 654// based on http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab. 655// The script must open a new tab, set its window.opener to null, and navigate 656// it to a cross-site URL. It should also work for meta-refreshes. 657// See http://crbug.com/93517. 658IN_PROC_BROWSER_TEST_F(BrowserTest, NullOpenerRedirectForksProcess) { 659 CommandLine::ForCurrentProcess()->AppendSwitch( 660 switches::kDisablePopupBlocking); 661 662 // Create http and https servers for a cross-site transition. 663 ASSERT_TRUE(test_server()->Start()); 664 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 665 net::SpawnedTestServer::kLocalhost, 666 base::FilePath(kDocRoot)); 667 ASSERT_TRUE(https_test_server.Start()); 668 GURL http_url(test_server()->GetURL("files/title1.html")); 669 GURL https_url(https_test_server.GetURL(std::string())); 670 671 // Start with an http URL. 672 ui_test_utils::NavigateToURL(browser(), http_url); 673 WebContents* oldtab = browser()->tab_strip_model()->GetActiveWebContents(); 674 content::RenderProcessHost* process = oldtab->GetRenderProcessHost(); 675 676 // Now open a tab to a blank page, set its opener to null, and redirect it 677 // cross-site. 678 std::string redirect_popup = "w=window.open();"; 679 redirect_popup += "w.opener=null;"; 680 redirect_popup += "w.document.location=\""; 681 redirect_popup += https_url.spec(); 682 redirect_popup += "\";"; 683 684 content::WindowedNotificationObserver popup_observer( 685 chrome::NOTIFICATION_TAB_ADDED, 686 content::NotificationService::AllSources()); 687 content::WindowedNotificationObserver nav_observer( 688 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 689 content::NotificationService::AllSources()); 690 oldtab->GetRenderViewHost()-> 691 ExecuteJavascriptInWebFrame(string16(), ASCIIToUTF16(redirect_popup)); 692 693 // Wait for popup window to appear and finish navigating. 694 popup_observer.Wait(); 695 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 696 WebContents* newtab = browser()->tab_strip_model()->GetActiveWebContents(); 697 EXPECT_TRUE(newtab); 698 EXPECT_NE(oldtab, newtab); 699 nav_observer.Wait(); 700 ASSERT_TRUE(newtab->GetController().GetLastCommittedEntry()); 701 EXPECT_EQ(https_url.spec(), 702 newtab->GetController().GetLastCommittedEntry()->GetURL().spec()); 703 704 // Popup window should not be in the opener's process. 705 content::RenderProcessHost* popup_process = 706 newtab->GetRenderProcessHost(); 707 EXPECT_NE(process, popup_process); 708 709 // Now open a tab to a blank page, set its opener to null, and use a 710 // meta-refresh to navigate it instead. 711 std::string refresh_popup = "w=window.open();"; 712 refresh_popup += "w.opener=null;"; 713 refresh_popup += "w.document.write("; 714 refresh_popup += "'<META HTTP-EQUIV=\"refresh\" content=\"0; url="; 715 refresh_popup += https_url.spec(); 716 refresh_popup += "\">');w.document.close();"; 717 718 content::WindowedNotificationObserver popup_observer2( 719 chrome::NOTIFICATION_TAB_ADDED, 720 content::NotificationService::AllSources()); 721 content::WindowedNotificationObserver nav_observer2( 722 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 723 content::NotificationService::AllSources()); 724 oldtab->GetRenderViewHost()-> 725 ExecuteJavascriptInWebFrame(string16(), ASCIIToUTF16(refresh_popup)); 726 727 // Wait for popup window to appear and finish navigating. 728 popup_observer2.Wait(); 729 ASSERT_EQ(3, browser()->tab_strip_model()->count()); 730 WebContents* newtab2 = browser()->tab_strip_model()->GetActiveWebContents(); 731 EXPECT_TRUE(newtab2); 732 EXPECT_NE(oldtab, newtab2); 733 nav_observer2.Wait(); 734 ASSERT_TRUE(newtab2->GetController().GetLastCommittedEntry()); 735 EXPECT_EQ(https_url.spec(), 736 newtab2->GetController().GetLastCommittedEntry()->GetURL().spec()); 737 738 // This popup window should also not be in the opener's process. 739 content::RenderProcessHost* popup_process2 = 740 newtab2->GetRenderProcessHost(); 741 EXPECT_NE(process, popup_process2); 742} 743 744// Tests that other popup navigations that do not follow the steps at 745// http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab will not 746// fork a new renderer process. 747IN_PROC_BROWSER_TEST_F(BrowserTest, OtherRedirectsDontForkProcess) { 748 CommandLine::ForCurrentProcess()->AppendSwitch( 749 switches::kDisablePopupBlocking); 750 751 // Create http and https servers for a cross-site transition. 752 ASSERT_TRUE(test_server()->Start()); 753 net::SpawnedTestServer https_test_server(net::SpawnedTestServer::TYPE_HTTPS, 754 net::SpawnedTestServer::kLocalhost, 755 base::FilePath(kDocRoot)); 756 ASSERT_TRUE(https_test_server.Start()); 757 GURL http_url(test_server()->GetURL("files/title1.html")); 758 GURL https_url(https_test_server.GetURL(std::string())); 759 760 // Start with an http URL. 761 ui_test_utils::NavigateToURL(browser(), http_url); 762 WebContents* oldtab = browser()->tab_strip_model()->GetActiveWebContents(); 763 content::RenderProcessHost* process = oldtab->GetRenderProcessHost(); 764 765 // Now open a tab to a blank page, set its opener to null, and redirect it 766 // cross-site. 767 std::string dont_fork_popup = "w=window.open();"; 768 dont_fork_popup += "w.document.location=\""; 769 dont_fork_popup += https_url.spec(); 770 dont_fork_popup += "\";"; 771 772 content::WindowedNotificationObserver popup_observer( 773 chrome::NOTIFICATION_TAB_ADDED, 774 content::NotificationService::AllSources()); 775 content::WindowedNotificationObserver nav_observer( 776 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 777 content::NotificationService::AllSources()); 778 oldtab->GetRenderViewHost()-> 779 ExecuteJavascriptInWebFrame(string16(), ASCIIToUTF16(dont_fork_popup)); 780 781 // Wait for popup window to appear and finish navigating. 782 popup_observer.Wait(); 783 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 784 WebContents* newtab = browser()->tab_strip_model()->GetActiveWebContents(); 785 EXPECT_TRUE(newtab); 786 EXPECT_NE(oldtab, newtab); 787 nav_observer.Wait(); 788 ASSERT_TRUE(newtab->GetController().GetLastCommittedEntry()); 789 EXPECT_EQ(https_url.spec(), 790 newtab->GetController().GetLastCommittedEntry()->GetURL().spec()); 791 792 // Popup window should still be in the opener's process. 793 content::RenderProcessHost* popup_process = 794 newtab->GetRenderProcessHost(); 795 EXPECT_EQ(process, popup_process); 796 797 // Same thing if the current tab tries to navigate itself. 798 std::string navigate_str = "document.location=\""; 799 navigate_str += https_url.spec(); 800 navigate_str += "\";"; 801 802 content::WindowedNotificationObserver nav_observer2( 803 content::NOTIFICATION_NAV_ENTRY_COMMITTED, 804 content::NotificationService::AllSources()); 805 oldtab->GetRenderViewHost()-> 806 ExecuteJavascriptInWebFrame(string16(), ASCIIToUTF16(navigate_str)); 807 nav_observer2.Wait(); 808 ASSERT_TRUE(oldtab->GetController().GetLastCommittedEntry()); 809 EXPECT_EQ(https_url.spec(), 810 oldtab->GetController().GetLastCommittedEntry()->GetURL().spec()); 811 812 // Original window should still be in the original process. 813 content::RenderProcessHost* new_process = newtab->GetRenderProcessHost(); 814 EXPECT_EQ(process, new_process); 815} 816 817// Test that get_process_idle_time() returns reasonable values when compared 818// with time deltas measured locally. 819IN_PROC_BROWSER_TEST_F(BrowserTest, RenderIdleTime) { 820 base::TimeTicks start = base::TimeTicks::Now(); 821 ui_test_utils::NavigateToURL( 822 browser(), ui_test_utils::GetTestUrl( 823 base::FilePath(base::FilePath::kCurrentDirectory), 824 base::FilePath(kTitle1File))); 825 content::RenderProcessHost::iterator it( 826 content::RenderProcessHost::AllHostsIterator()); 827 for (; !it.IsAtEnd(); it.Advance()) { 828 base::TimeDelta renderer_td = 829 it.GetCurrentValue()->GetChildProcessIdleTime(); 830 base::TimeDelta browser_td = base::TimeTicks::Now() - start; 831 EXPECT_TRUE(browser_td >= renderer_td); 832 } 833} 834 835// Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http 836// and https and disabled for chrome://, about:// etc. 837// TODO(pinkerton): Disable app-mode in the model until we implement it 838// on the Mac. http://crbug.com/13148 839#if !defined(OS_MACOSX) 840IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutFile) { 841 CommandUpdater* command_updater = 842 browser()->command_controller()->command_updater(); 843 844 static const base::FilePath::CharType* kEmptyFile = 845 FILE_PATH_LITERAL("empty.html"); 846 GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( 847 base::FilePath::kCurrentDirectory), base::FilePath(kEmptyFile))); 848 ASSERT_TRUE(file_url.SchemeIs(chrome::kFileScheme)); 849 ui_test_utils::NavigateToURL(browser(), file_url); 850 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 851} 852 853IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutHttp) { 854 CommandUpdater* command_updater = 855 browser()->command_controller()->command_updater(); 856 857 ASSERT_TRUE(test_server()->Start()); 858 GURL http_url(test_server()->GetURL(std::string())); 859 ASSERT_TRUE(http_url.SchemeIs(chrome::kHttpScheme)); 860 ui_test_utils::NavigateToURL(browser(), http_url); 861 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 862} 863 864IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutHttps) { 865 CommandUpdater* command_updater = 866 browser()->command_controller()->command_updater(); 867 868 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTPS, 869 net::SpawnedTestServer::kLocalhost, 870 base::FilePath(kDocRoot)); 871 ASSERT_TRUE(test_server.Start()); 872 GURL https_url(test_server.GetURL("/")); 873 ASSERT_TRUE(https_url.SchemeIs(chrome::kHttpsScheme)); 874 ui_test_utils::NavigateToURL(browser(), https_url); 875 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 876} 877 878IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutFtp) { 879 CommandUpdater* command_updater = 880 browser()->command_controller()->command_updater(); 881 882 net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_FTP, 883 net::SpawnedTestServer::kLocalhost, 884 base::FilePath(kDocRoot)); 885 ASSERT_TRUE(test_server.Start()); 886 GURL ftp_url(test_server.GetURL(std::string())); 887 ASSERT_TRUE(ftp_url.SchemeIs(chrome::kFtpScheme)); 888 ui_test_utils::NavigateToURL(browser(), ftp_url); 889 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 890} 891 892IN_PROC_BROWSER_TEST_F(BrowserTest, CommandCreateAppShortcutInvalid) { 893 CommandUpdater* command_updater = 894 browser()->command_controller()->command_updater(); 895 896 // Urls that should not have shortcuts. 897 GURL new_tab_url(chrome::kChromeUINewTabURL); 898 ui_test_utils::NavigateToURL(browser(), new_tab_url); 899 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 900 901 GURL history_url(chrome::kChromeUIHistoryURL); 902 ui_test_utils::NavigateToURL(browser(), history_url); 903 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 904 905 GURL downloads_url(chrome::kChromeUIDownloadsURL); 906 ui_test_utils::NavigateToURL(browser(), downloads_url); 907 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 908 909 GURL blank_url(content::kAboutBlankURL); 910 ui_test_utils::NavigateToURL(browser(), blank_url); 911 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_CREATE_SHORTCUTS)); 912} 913 914// Change a tab into an application window. 915// DISABLED: http://crbug.com/72310 916IN_PROC_BROWSER_TEST_F(BrowserTest, DISABLED_ConvertTabToAppShortcut) { 917 ASSERT_TRUE(test_server()->Start()); 918 GURL http_url(test_server()->GetURL(std::string())); 919 ASSERT_TRUE(http_url.SchemeIs(chrome::kHttpScheme)); 920 921 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 922 WebContents* initial_tab = browser()->tab_strip_model()->GetWebContentsAt(0); 923 WebContents* app_tab = chrome::AddSelectedTabWithURL( 924 browser(), http_url, content::PAGE_TRANSITION_TYPED); 925 ASSERT_EQ(2, browser()->tab_strip_model()->count()); 926 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(), 927 browser()->host_desktop_type())); 928 929 // Normal tabs should accept load drops. 930 EXPECT_TRUE(initial_tab->GetMutableRendererPrefs()->can_accept_load_drops); 931 EXPECT_TRUE(app_tab->GetMutableRendererPrefs()->can_accept_load_drops); 932 933 // Turn |app_tab| into a tab in an app panel. 934 chrome::ConvertTabToAppWindow(browser(), app_tab); 935 936 // The launch should have created a new browser. 937 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 938 browser()->host_desktop_type())); 939 940 // Find the new browser. 941 Browser* app_browser = NULL; 942 for (chrome::BrowserIterator it; !it.done() && !app_browser; it.Next()) { 943 if (*it != browser()) 944 app_browser = *it; 945 } 946 ASSERT_TRUE(app_browser); 947 948 // Check that the tab contents is in the new browser, and not in the old. 949 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 950 ASSERT_EQ(initial_tab, browser()->tab_strip_model()->GetWebContentsAt(0)); 951 952 // Check that the appliaction browser has a single tab, and that tab contains 953 // the content that we app-ified. 954 ASSERT_EQ(1, app_browser->tab_strip_model()->count()); 955 ASSERT_EQ(app_tab, app_browser->tab_strip_model()->GetWebContentsAt(0)); 956 957 // Normal tabs should accept load drops. 958 EXPECT_TRUE(initial_tab->GetMutableRendererPrefs()->can_accept_load_drops); 959 960 // The tab in an app window should not. 961 EXPECT_FALSE(app_tab->GetMutableRendererPrefs()->can_accept_load_drops); 962} 963 964#endif // !defined(OS_MACOSX) 965 966// Test RenderView correctly send back favicon url for web page that redirects 967// to an anchor in javascript body.onload handler. 968IN_PROC_BROWSER_TEST_F(BrowserTest, 969 DISABLED_FaviconOfOnloadRedirectToAnchorPage) { 970 ASSERT_TRUE(test_server()->Start()); 971 GURL url(test_server()->GetURL("files/onload_redirect_to_anchor.html")); 972 GURL expected_favicon_url(test_server()->GetURL("files/test.png")); 973 974 ui_test_utils::NavigateToURL(browser(), url); 975 976 NavigationEntry* entry = browser()->tab_strip_model()-> 977 GetActiveWebContents()->GetController().GetActiveEntry(); 978 EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec()); 979} 980 981#if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN) 982// http://crbug.com/83828. On Mac 10.6, the failure rate is 14% 983#define MAYBE_FaviconChange DISABLED_FaviconChange 984#else 985#define MAYBE_FaviconChange FaviconChange 986#endif 987// Test that an icon can be changed from JS. 988IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_FaviconChange) { 989 static const base::FilePath::CharType* kFile = 990 FILE_PATH_LITERAL("onload_change_favicon.html"); 991 GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( 992 base::FilePath::kCurrentDirectory), base::FilePath(kFile))); 993 ASSERT_TRUE(file_url.SchemeIs(chrome::kFileScheme)); 994 ui_test_utils::NavigateToURL(browser(), file_url); 995 996 NavigationEntry* entry = browser()->tab_strip_model()-> 997 GetActiveWebContents()->GetController().GetActiveEntry(); 998 static const base::FilePath::CharType* kIcon = 999 FILE_PATH_LITERAL("test1.png"); 1000 GURL expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath( 1001 base::FilePath::kCurrentDirectory), base::FilePath(kIcon))); 1002 EXPECT_EQ(expected_favicon_url.spec(), entry->GetFavicon().url.spec()); 1003} 1004 1005// http://crbug.com/172336 1006#if defined(OS_WIN) 1007#define MAYBE_TabClosingWhenRemovingExtension \ 1008 DISABLED_TabClosingWhenRemovingExtension 1009#else 1010#define MAYBE_TabClosingWhenRemovingExtension TabClosingWhenRemovingExtension 1011#endif 1012// Makes sure TabClosing is sent when uninstalling an extension that is an app 1013// tab. 1014IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_TabClosingWhenRemovingExtension) { 1015 ASSERT_TRUE(test_server()->Start()); 1016 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1017 GURL url(test_server()->GetURL("empty.html")); 1018 TabStripModel* model = browser()->tab_strip_model(); 1019 1020 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1021 1022 const Extension* extension_app = GetExtension(); 1023 1024 ui_test_utils::NavigateToURL(browser(), url); 1025 1026 WebContents* app_contents = WebContents::Create( 1027 WebContents::CreateParams(browser()->profile())); 1028 extensions::TabHelper::CreateForWebContents(app_contents); 1029 extensions::TabHelper* extensions_tab_helper = 1030 extensions::TabHelper::FromWebContents(app_contents); 1031 extensions_tab_helper->SetExtensionApp(extension_app); 1032 1033 model->AddWebContents(app_contents, 0, content::PageTransitionFromInt(0), 1034 TabStripModel::ADD_NONE); 1035 model->SetTabPinned(0, true); 1036 ui_test_utils::NavigateToURL(browser(), url); 1037 1038 MockTabStripModelObserver observer; 1039 model->AddObserver(&observer); 1040 1041 // Uninstall the extension and make sure TabClosing is sent. 1042 ExtensionService* service = extensions::ExtensionSystem::Get( 1043 browser()->profile())->extension_service(); 1044 service->UninstallExtension(GetExtension()->id(), false, NULL); 1045 EXPECT_EQ(1, observer.closing_count()); 1046 1047 model->RemoveObserver(&observer); 1048 1049 // There should only be one tab now. 1050 ASSERT_EQ(1, browser()->tab_strip_model()->count()); 1051} 1052 1053#if !defined(OS_MACOSX) 1054// Open with --app-id=<id>, and see that an app window opens. 1055IN_PROC_BROWSER_TEST_F(BrowserTest, AppIdSwitch) { 1056 ASSERT_TRUE(test_server()->Start()); 1057 1058 // Load an app. 1059 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1060 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1061 const Extension* extension_app = GetExtension(); 1062 1063 CommandLine command_line(CommandLine::NO_PROGRAM); 1064 command_line.AppendSwitchASCII(switches::kAppId, extension_app->id()); 1065 1066 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? 1067 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 1068 StartupBrowserCreatorImpl launch(base::FilePath(), command_line, first_run); 1069 ASSERT_TRUE(launch.OpenApplicationWindow(browser()->profile(), NULL)); 1070 1071 // Check that the new browser has an app name. 1072 // The launch should have created a new browser. 1073 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1074 browser()->host_desktop_type())); 1075 1076 // Find the new browser. 1077 Browser* new_browser = NULL; 1078 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) { 1079 if (*it != browser()) 1080 new_browser = *it; 1081 } 1082 ASSERT_TRUE(new_browser); 1083 ASSERT_TRUE(new_browser != browser()); 1084 1085 // The browser's app_name should include the app's ID. 1086 ASSERT_NE( 1087 new_browser->app_name_.find(extension_app->id()), 1088 std::string::npos) << new_browser->app_name_; 1089} 1090#endif 1091 1092// Tests that the CLD (Compact Language Detection) works properly. 1093IN_PROC_BROWSER_TEST_F(BrowserTest, PageLanguageDetection) { 1094 ASSERT_TRUE(test_server()->Start()); 1095 1096 //std::string lang; 1097 LanguageDetectionDetails details; 1098 1099 // Open a new tab with a page in English. 1100 AddTabAtIndex(0, GURL(test_server()->GetURL("files/english_page.html")), 1101 content::PAGE_TRANSITION_TYPED); 1102 1103 WebContents* current_web_contents = 1104 browser()->tab_strip_model()->GetActiveWebContents(); 1105 TranslateTabHelper* translate_tab_helper = 1106 TranslateTabHelper::FromWebContents(current_web_contents); 1107 content::Source<WebContents> source(current_web_contents); 1108 1109 ui_test_utils::WindowedNotificationObserverWithDetails< 1110 LanguageDetectionDetails> 1111 en_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 1112 source); 1113 EXPECT_EQ("", translate_tab_helper->language_state().original_language()); 1114 en_language_detected_signal.Wait(); 1115 EXPECT_TRUE(en_language_detected_signal.GetDetailsFor( 1116 source.map_key(), &details)); 1117 EXPECT_EQ("en", details.adopted_language); 1118 EXPECT_EQ("en", translate_tab_helper->language_state().original_language()); 1119 1120 // Now navigate to a page in French. 1121 ui_test_utils::WindowedNotificationObserverWithDetails< 1122 LanguageDetectionDetails> 1123 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, 1124 source); 1125 ui_test_utils::NavigateToURL( 1126 browser(), GURL(test_server()->GetURL("files/french_page.html"))); 1127 fr_language_detected_signal.Wait(); 1128 details.adopted_language.clear(); 1129 EXPECT_TRUE(fr_language_detected_signal.GetDetailsFor( 1130 source.map_key(), &details)); 1131 EXPECT_EQ("fr", details.adopted_language); 1132 EXPECT_EQ("fr", translate_tab_helper->language_state().original_language()); 1133} 1134 1135// Chromeos defaults to restoring the last session, so this test isn't 1136// applicable. 1137#if !defined(OS_CHROMEOS) 1138#if defined(OS_MACOSX) 1139// Crashy, http://crbug.com/38522 1140#define RestorePinnedTabs DISABLED_RestorePinnedTabs 1141#endif 1142// Makes sure pinned tabs are restored correctly on start. 1143IN_PROC_BROWSER_TEST_F(BrowserTest, RestorePinnedTabs) { 1144 ASSERT_TRUE(test_server()->Start()); 1145 1146 // Add an pinned app tab. 1147 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1148 GURL url(test_server()->GetURL("empty.html")); 1149 TabStripModel* model = browser()->tab_strip_model(); 1150 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1151 const Extension* extension_app = GetExtension(); 1152 ui_test_utils::NavigateToURL(browser(), url); 1153 WebContents* app_contents = WebContents::Create( 1154 WebContents::CreateParams(browser()->profile())); 1155 extensions::TabHelper::CreateForWebContents(app_contents); 1156 extensions::TabHelper* extensions_tab_helper = 1157 extensions::TabHelper::FromWebContents(app_contents); 1158 extensions_tab_helper->SetExtensionApp(extension_app); 1159 model->AddWebContents(app_contents, 0, content::PageTransitionFromInt(0), 1160 TabStripModel::ADD_NONE); 1161 model->SetTabPinned(0, true); 1162 ui_test_utils::NavigateToURL(browser(), url); 1163 1164 // Add a non pinned tab. 1165 chrome::NewTab(browser()); 1166 1167 // Add a pinned non-app tab. 1168 chrome::NewTab(browser()); 1169 ui_test_utils::NavigateToURL(browser(), GURL(content::kAboutBlankURL)); 1170 model->SetTabPinned(2, true); 1171 1172 // Write out the pinned tabs. 1173 PinnedTabCodec::WritePinnedTabs(browser()->profile()); 1174 1175 // Simulate launching again. 1176 CommandLine dummy(CommandLine::NO_PROGRAM); 1177 chrome::startup::IsFirstRun first_run = first_run::IsChromeFirstRun() ? 1178 chrome::startup::IS_FIRST_RUN : chrome::startup::IS_NOT_FIRST_RUN; 1179 StartupBrowserCreatorImpl launch(base::FilePath(), dummy, first_run); 1180 launch.profile_ = browser()->profile(); 1181 launch.ProcessStartupURLs(std::vector<GURL>(), 1182 browser()->host_desktop_type()); 1183 1184 // The launch should have created a new browser. 1185 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1186 browser()->host_desktop_type())); 1187 1188 // Find the new browser. 1189 Browser* new_browser = NULL; 1190 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) { 1191 if (*it != browser()) 1192 new_browser = *it; 1193 } 1194 ASSERT_TRUE(new_browser); 1195 ASSERT_TRUE(new_browser != browser()); 1196 1197 // We should get back an additional tab for the app, and another for the 1198 // default home page. 1199 ASSERT_EQ(3, new_browser->tab_strip_model()->count()); 1200 1201 // Make sure the state matches. 1202 TabStripModel* new_model = new_browser->tab_strip_model(); 1203 EXPECT_TRUE(new_model->IsAppTab(0)); 1204 EXPECT_FALSE(new_model->IsAppTab(1)); 1205 EXPECT_FALSE(new_model->IsAppTab(2)); 1206 1207 EXPECT_TRUE(new_model->IsTabPinned(0)); 1208 EXPECT_TRUE(new_model->IsTabPinned(1)); 1209 EXPECT_FALSE(new_model->IsTabPinned(2)); 1210 1211 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL), 1212 new_model->GetWebContentsAt(2)->GetURL()); 1213 1214 EXPECT_TRUE( 1215 extensions::TabHelper::FromWebContents( 1216 new_model->GetWebContentsAt(0))->extension_app() == extension_app); 1217} 1218#endif // !defined(OS_CHROMEOS) 1219 1220// This test verifies we don't crash when closing the last window and the app 1221// menu is showing. 1222// TODO(linux_aura) http://crbug.com/163931 1223#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 1224#define MAYBE_CloseWithAppMenuOpen DISABLED_CloseWithAppMenuOpen 1225#else 1226#define MAYBE_CloseWithAppMenuOpen CloseWithAppMenuOpen 1227#endif 1228IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_CloseWithAppMenuOpen) { 1229 if (browser_defaults::kBrowserAliveWithNoWindows) 1230 return; 1231 1232 // We need a message loop running for menus on windows. 1233 base::MessageLoop::current()->PostTask( 1234 FROM_HERE, base::Bind(&RunCloseWithAppMenuCallback, browser())); 1235} 1236 1237#if !defined(OS_MACOSX) 1238IN_PROC_BROWSER_TEST_F(BrowserTest, OpenAppWindowLikeNtp) { 1239 ASSERT_TRUE(test_server()->Start()); 1240 1241 // Load an app 1242 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1243 ASSERT_TRUE(LoadExtension(test_data_dir_.AppendASCII("app/"))); 1244 const Extension* extension_app = GetExtension(); 1245 1246 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would. 1247 WebContents* app_window = chrome::OpenApplication( 1248 chrome::AppLaunchParams(browser()->profile(), extension_app, 1249 extension_misc::LAUNCH_WINDOW, NEW_WINDOW)); 1250 ASSERT_TRUE(app_window); 1251 1252 // Apps launched in a window from the NTP have an extensions tab helper but 1253 // do not have extension_app set in it. 1254 ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window)); 1255 EXPECT_FALSE( 1256 extensions::TabHelper::FromWebContents(app_window)->extension_app()); 1257 EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app), 1258 app_window->GetURL()); 1259 1260 // The launch should have created a new browser. 1261 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(), 1262 browser()->host_desktop_type())); 1263 1264 // Find the new browser. 1265 Browser* new_browser = NULL; 1266 for (chrome::BrowserIterator it; !it.done() && !new_browser; it.Next()) { 1267 if (*it != browser()) 1268 new_browser = *it; 1269 } 1270 ASSERT_TRUE(new_browser); 1271 ASSERT_TRUE(new_browser != browser()); 1272 1273 EXPECT_TRUE(new_browser->is_app()); 1274 1275 // The browser's app name should include the extension's id. 1276 std::string app_name = new_browser->app_name_; 1277 EXPECT_NE(app_name.find(extension_app->id()), std::string::npos) 1278 << "Name " << app_name << " should contain id "<< extension_app->id(); 1279} 1280#endif // !defined(OS_MACOSX) 1281 1282// Makes sure the browser doesn't crash when 1283// set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked. 1284IN_PROC_BROWSER_TEST_F(BrowserTest, StartMaximized) { 1285 Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; 1286 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(types); ++i) { 1287 Browser::CreateParams params(types[i], browser()->profile(), 1288 browser()->host_desktop_type()); 1289 params.initial_show_state = ui::SHOW_STATE_MAXIMIZED; 1290 AddBlankTabAndShow(new Browser(params)); 1291 } 1292} 1293 1294// Aura doesn't support minimized window. crbug.com/104571. 1295#if defined(USE_AURA) 1296#define MAYBE_StartMinimized DISABLED_StartMinimized 1297#else 1298#define MAYBE_StartMinimized StartMinimized 1299#endif 1300// Makes sure the browser doesn't crash when 1301// set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked. 1302IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_StartMinimized) { 1303 Browser::Type types[] = { Browser::TYPE_TABBED, Browser::TYPE_POPUP }; 1304 for (size_t i = 0; i < ARRAYSIZE_UNSAFE(types); ++i) { 1305 Browser::CreateParams params(types[i], browser()->profile(), 1306 browser()->host_desktop_type()); 1307 params.initial_show_state = ui::SHOW_STATE_MINIMIZED; 1308 AddBlankTabAndShow(new Browser(params)); 1309 } 1310} 1311 1312// Makes sure the forward button is disabled immediately when navigating 1313// forward to a slow-to-commit page. 1314IN_PROC_BROWSER_TEST_F(BrowserTest, ForwardDisabledOnForward) { 1315 GURL blank_url(content::kAboutBlankURL); 1316 ui_test_utils::NavigateToURL(browser(), blank_url); 1317 1318 ui_test_utils::NavigateToURL( 1319 browser(), ui_test_utils::GetTestUrl( 1320 base::FilePath(base::FilePath::kCurrentDirectory), 1321 base::FilePath(kTitle1File))); 1322 1323 content::WindowedNotificationObserver back_nav_load_observer( 1324 content::NOTIFICATION_LOAD_STOP, 1325 content::Source<NavigationController>( 1326 &browser()->tab_strip_model()->GetActiveWebContents()-> 1327 GetController())); 1328 chrome::GoBack(browser(), CURRENT_TAB); 1329 back_nav_load_observer.Wait(); 1330 CommandUpdater* command_updater = 1331 browser()->command_controller()->command_updater(); 1332 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_FORWARD)); 1333 1334 content::WindowedNotificationObserver forward_nav_load_observer( 1335 content::NOTIFICATION_LOAD_STOP, 1336 content::Source<NavigationController>( 1337 &browser()->tab_strip_model()->GetActiveWebContents()-> 1338 GetController())); 1339 chrome::GoForward(browser(), CURRENT_TAB); 1340 // This check will happen before the navigation completes, since the browser 1341 // won't process the renderer's response until the Wait() call below. 1342 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_FORWARD)); 1343 forward_nav_load_observer.Wait(); 1344} 1345 1346// Makes sure certain commands are disabled when Incognito mode is forced. 1347IN_PROC_BROWSER_TEST_F(BrowserTest, DisableMenuItemsWhenIncognitoIsForced) { 1348 CommandUpdater* command_updater = 1349 browser()->command_controller()->command_updater(); 1350 // At the beginning, all commands are enabled. 1351 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1352 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1353 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1354 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1355 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1356 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1357 1358 // Set Incognito to FORCED. 1359 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), 1360 IncognitoModePrefs::FORCED); 1361 // Bookmarks & Settings commands should get disabled. 1362 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1363 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1364 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1365 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1366 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1367 // New Incognito Window command, however, should be enabled. 1368 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1369 1370 // Create a new browser. 1371 Browser* new_browser = 1372 new Browser(Browser::CreateParams( 1373 browser()->profile()->GetOffTheRecordProfile(), 1374 browser()->host_desktop_type())); 1375 CommandUpdater* new_command_updater = 1376 new_browser->command_controller()->command_updater(); 1377 // It should have Bookmarks & Settings commands disabled by default. 1378 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1379 EXPECT_FALSE(new_command_updater->IsCommandEnabled( 1380 IDC_SHOW_BOOKMARK_MANAGER)); 1381 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1382 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1383 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_OPTIONS)); 1384 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1385} 1386 1387// Makes sure New Incognito Window command is disabled when Incognito mode is 1388// not available. 1389IN_PROC_BROWSER_TEST_F(BrowserTest, 1390 NoNewIncognitoWindowWhenIncognitoIsDisabled) { 1391 CommandUpdater* command_updater = 1392 browser()->command_controller()->command_updater(); 1393 // Set Incognito to DISABLED. 1394 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), 1395 IncognitoModePrefs::DISABLED); 1396 // Make sure New Incognito Window command is disabled. All remaining commands 1397 // should be enabled. 1398 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1399 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1400 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1401 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1402 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1403 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1404 1405 // Create a new browser. 1406 Browser* new_browser = 1407 new Browser(Browser::CreateParams(browser()->profile(), 1408 browser()->host_desktop_type())); 1409 CommandUpdater* new_command_updater = 1410 new_browser->command_controller()->command_updater(); 1411 EXPECT_FALSE(new_command_updater->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW)); 1412 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1413 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1414 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1415 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1416 EXPECT_TRUE(new_command_updater->IsCommandEnabled(IDC_OPTIONS)); 1417} 1418 1419// Makes sure Extensions and Settings commands are disabled in certain 1420// circumstances even though normally they should stay enabled. 1421IN_PROC_BROWSER_TEST_F(BrowserTest, 1422 DisableExtensionsAndSettingsWhenIncognitoIsDisabled) { 1423 CommandUpdater* command_updater = 1424 browser()->command_controller()->command_updater(); 1425 // Disable extensions. This should disable Extensions menu. 1426 extensions::ExtensionSystem::Get(browser()->profile())->extension_service()-> 1427 set_extensions_enabled(false); 1428 // Set Incognito to DISABLED. 1429 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(), 1430 IncognitoModePrefs::DISABLED); 1431 // Make sure Manage Extensions command is disabled. 1432 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1433 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_NEW_WINDOW)); 1434 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER)); 1435 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1436 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1437 1438 // Create a popup (non-main-UI-type) browser. Settings command as well 1439 // as Extensions should be disabled. 1440 Browser* popup_browser = new Browser( 1441 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), 1442 browser()->host_desktop_type())); 1443 CommandUpdater* popup_command_updater = 1444 popup_browser->command_controller()->command_updater(); 1445 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_MANAGE_EXTENSIONS)); 1446 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_OPTIONS)); 1447 EXPECT_TRUE(popup_command_updater->IsCommandEnabled( 1448 IDC_SHOW_BOOKMARK_MANAGER)); 1449 EXPECT_FALSE(popup_command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1450} 1451 1452// Makes sure Extensions and Settings commands are disabled in certain 1453// circumstances even though normally they should stay enabled. 1454IN_PROC_BROWSER_TEST_F(BrowserTest, 1455 DisableOptionsAndImportMenuItemsConsistently) { 1456 // Create a popup browser. 1457 Browser* popup_browser = new Browser( 1458 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile(), 1459 browser()->host_desktop_type())); 1460 CommandUpdater* command_updater = 1461 popup_browser->command_controller()->command_updater(); 1462 // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI. 1463 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1464 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1465 1466 // Set Incognito to FORCED. 1467 IncognitoModePrefs::SetAvailability(popup_browser->profile()->GetPrefs(), 1468 IncognitoModePrefs::FORCED); 1469 // OPTIONS and IMPORT_SETTINGS are disabled when Incognito is forced. 1470 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1471 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1472 // Set Incognito to AVAILABLE. 1473 IncognitoModePrefs::SetAvailability(popup_browser->profile()->GetPrefs(), 1474 IncognitoModePrefs::ENABLED); 1475 // OPTIONS and IMPORT_SETTINGS are still disabled since it is a non-normal UI. 1476 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_OPTIONS)); 1477 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_IMPORT_SETTINGS)); 1478} 1479 1480namespace { 1481 1482void OnZoomLevelChanged(const base::Closure& callback, 1483 const HostZoomMap::ZoomLevelChange& host) { 1484 callback.Run(); 1485} 1486 1487} // namespace 1488 1489#if defined(OS_WIN) 1490// Flakes regularly on Windows XP 1491// http://crbug.com/146040 1492#define MAYBE_PageZoom DISABLED_PageZoom 1493#else 1494#define MAYBE_PageZoom PageZoom 1495#endif 1496IN_PROC_BROWSER_TEST_F(BrowserTest, MAYBE_PageZoom) { 1497 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1498 bool enable_plus, enable_minus; 1499 1500 { 1501 scoped_refptr<content::MessageLoopRunner> loop_runner( 1502 new content::MessageLoopRunner); 1503 content::HostZoomMap::ZoomLevelChangedCallback callback( 1504 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure())); 1505 content::HostZoomMap::GetForBrowserContext( 1506 browser()->profile())->AddZoomLevelChangedCallback(callback); 1507 chrome::Zoom(browser(), content::PAGE_ZOOM_IN); 1508 loop_runner->Run(); 1509 content::HostZoomMap::GetForBrowserContext( 1510 browser()->profile())->RemoveZoomLevelChangedCallback(callback); 1511 EXPECT_EQ(contents->GetZoomPercent(&enable_plus, &enable_minus), 110); 1512 EXPECT_TRUE(enable_plus); 1513 EXPECT_TRUE(enable_minus); 1514 } 1515 1516 { 1517 scoped_refptr<content::MessageLoopRunner> loop_runner( 1518 new content::MessageLoopRunner); 1519 content::HostZoomMap::ZoomLevelChangedCallback callback( 1520 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure())); 1521 content::HostZoomMap::GetForBrowserContext( 1522 browser()->profile())->AddZoomLevelChangedCallback(callback); 1523 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET); 1524 loop_runner->Run(); 1525 content::HostZoomMap::GetForBrowserContext( 1526 browser()->profile())->RemoveZoomLevelChangedCallback(callback); 1527 EXPECT_EQ(contents->GetZoomPercent(&enable_plus, &enable_minus), 100); 1528 EXPECT_TRUE(enable_plus); 1529 EXPECT_TRUE(enable_minus); 1530 } 1531 1532 { 1533 scoped_refptr<content::MessageLoopRunner> loop_runner( 1534 new content::MessageLoopRunner); 1535 content::HostZoomMap::ZoomLevelChangedCallback callback( 1536 base::Bind(&OnZoomLevelChanged, loop_runner->QuitClosure())); 1537 content::HostZoomMap::GetForBrowserContext( 1538 browser()->profile())->AddZoomLevelChangedCallback(callback); 1539 chrome::Zoom(browser(), content::PAGE_ZOOM_OUT); 1540 loop_runner->Run(); 1541 content::HostZoomMap::GetForBrowserContext( 1542 browser()->profile())->RemoveZoomLevelChangedCallback(callback); 1543 EXPECT_EQ(contents->GetZoomPercent(&enable_plus, &enable_minus), 90); 1544 EXPECT_TRUE(enable_plus); 1545 EXPECT_TRUE(enable_minus); 1546 } 1547 1548 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET); 1549} 1550 1551IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCommandDisable) { 1552 ASSERT_TRUE(test_server()->Start()); 1553 host_resolver()->AddRule("www.example.com", "127.0.0.1"); 1554 GURL url(test_server()->GetURL("empty.html")); 1555 ui_test_utils::NavigateToURL(browser(), url); 1556 1557 CommandUpdater* command_updater = 1558 browser()->command_controller()->command_updater(); 1559 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE)); 1560 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT)); 1561 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE)); 1562 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU)); 1563 1564 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1565 1566 TestInterstitialPage* interstitial = NULL; 1567 { 1568 scoped_refptr<content::MessageLoopRunner> loop_runner( 1569 new content::MessageLoopRunner); 1570 1571 InterstitialObserver observer(contents, 1572 loop_runner->QuitClosure(), 1573 base::Closure()); 1574 interstitial = new TestInterstitialPage(contents, false, GURL()); 1575 loop_runner->Run(); 1576 } 1577 1578 EXPECT_TRUE(contents->ShowingInterstitialPage()); 1579 1580 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE)); 1581 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_PRINT)); 1582 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE)); 1583 EXPECT_FALSE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU)); 1584 1585 { 1586 scoped_refptr<content::MessageLoopRunner> loop_runner( 1587 new content::MessageLoopRunner); 1588 1589 InterstitialObserver observer(contents, 1590 base::Closure(), 1591 loop_runner->QuitClosure()); 1592 interstitial->Proceed(); 1593 loop_runner->Run(); 1594 // interstitial is deleted now. 1595 } 1596 1597 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_VIEW_SOURCE)); 1598 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_PRINT)); 1599 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_SAVE_PAGE)); 1600 EXPECT_TRUE(command_updater->IsCommandEnabled(IDC_ENCODING_MENU)); 1601} 1602 1603IN_PROC_BROWSER_TEST_F(BrowserTest, InterstitialCloseTab) { 1604 WebContents* contents = browser()->tab_strip_model()->GetActiveWebContents(); 1605 1606 { 1607 scoped_refptr<content::MessageLoopRunner> loop_runner( 1608 new content::MessageLoopRunner); 1609 1610 InterstitialObserver observer(contents, 1611 loop_runner->QuitClosure(), 1612 base::Closure()); 1613 // Interstitial will delete itself when we close the tab. 1614 new TestInterstitialPage(contents, false, GURL()); 1615 loop_runner->Run(); 1616 } 1617 1618 EXPECT_TRUE(contents->ShowingInterstitialPage()); 1619 1620 { 1621 scoped_refptr<content::MessageLoopRunner> loop_runner( 1622 new content::MessageLoopRunner); 1623 1624 InterstitialObserver observer(contents, 1625 base::Closure(), 1626 loop_runner->QuitClosure()); 1627 chrome::CloseTab(browser()); 1628 loop_runner->Run(); 1629 // interstitial is deleted now. 1630 } 1631} 1632 1633class MockWebContentsObserver : public WebContentsObserver { 1634 public: 1635 explicit MockWebContentsObserver(WebContents* web_contents) 1636 : WebContentsObserver(web_contents), 1637 got_user_gesture_(false) { 1638 } 1639 1640 virtual void DidGetUserGesture() OVERRIDE { 1641 got_user_gesture_ = true; 1642 } 1643 1644 bool got_user_gesture() const { 1645 return got_user_gesture_; 1646 } 1647 1648 void set_got_user_gesture(bool got_it) { 1649 got_user_gesture_ = got_it; 1650 } 1651 1652 private: 1653 bool got_user_gesture_; 1654 1655 DISALLOW_COPY_AND_ASSIGN(MockWebContentsObserver); 1656}; 1657 1658IN_PROC_BROWSER_TEST_F(BrowserTest, UserGesturesReported) { 1659 // Regression test for http://crbug.com/110707. Also tests that a user 1660 // gesture is sent when a normal navigation (via e.g. the omnibox) is 1661 // performed. 1662 WebContents* web_contents = 1663 browser()->tab_strip_model()->GetActiveWebContents(); 1664 MockWebContentsObserver mock_observer(web_contents); 1665 1666 ASSERT_TRUE(test_server()->Start()); 1667 GURL url(test_server()->GetURL("empty.html")); 1668 1669 ui_test_utils::NavigateToURL(browser(), url); 1670 EXPECT_TRUE(mock_observer.got_user_gesture()); 1671 1672 mock_observer.set_got_user_gesture(false); 1673 chrome::Reload(browser(), CURRENT_TAB); 1674 EXPECT_TRUE(mock_observer.got_user_gesture()); 1675} 1676 1677// TODO(ben): this test was never enabled. It has bit-rotted since being added. 1678// It originally lived in browser_unittest.cc, but has been moved here to make 1679// room for real browser unit tests. 1680#if 0 1681class BrowserTest2 : public InProcessBrowserTest { 1682 public: 1683 BrowserTest2() { 1684 host_resolver_proc_ = new net::RuleBasedHostResolverProc(NULL); 1685 // Avoid making external DNS lookups. In this test we don't need this 1686 // to succeed. 1687 host_resolver_proc_->AddSimulatedFailure("*.google.com"); 1688 scoped_host_resolver_proc_.Init(host_resolver_proc_.get()); 1689 } 1690 1691 private: 1692 scoped_refptr<net::RuleBasedHostResolverProc> host_resolver_proc_; 1693 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_; 1694}; 1695 1696IN_PROC_BROWSER_TEST_F(BrowserTest2, NoTabsInPopups) { 1697 chrome::RegisterAppPrefs(L"Test"); 1698 1699 // We start with a normal browser with one tab. 1700 EXPECT_EQ(1, browser()->tab_strip_model()->count()); 1701 1702 // Open a popup browser with a single blank foreground tab. 1703 Browser* popup_browser = new Browser( 1704 Browser::CreateParams(Browser::TYPE_POPUP, browser()->profile())); 1705 chrome::AddBlankTabAt(popup_browser, -1, true); 1706 EXPECT_EQ(1, popup_browser->tab_strip_model()->count()); 1707 1708 // Now try opening another tab in the popup browser. 1709 AddTabWithURLParams params1(url, content::PAGE_TRANSITION_TYPED); 1710 popup_browser->AddTabWithURL(¶ms1); 1711 EXPECT_EQ(popup_browser, params1.target); 1712 1713 // The popup should still only have one tab. 1714 EXPECT_EQ(1, popup_browser->tab_strip_model()->count()); 1715 1716 // The normal browser should now have two. 1717 EXPECT_EQ(2, browser()->tab_strip_model()->count()); 1718 1719 // Open an app frame browser with a single blank foreground tab. 1720 Browser* app_browser = new Browser(Browser::CreateParams::CreateForApp( 1721 L"Test", browser()->profile(), false)); 1722 chrome::AddBlankTabAt(app_browser, -1, true); 1723 EXPECT_EQ(1, app_browser->tab_strip_model()->count()); 1724 1725 // Now try opening another tab in the app browser. 1726 AddTabWithURLParams params2(GURL(content::kAboutBlankURL), 1727 content::PAGE_TRANSITION_TYPED); 1728 app_browser->AddTabWithURL(¶ms2); 1729 EXPECT_EQ(app_browser, params2.target); 1730 1731 // The popup should still only have one tab. 1732 EXPECT_EQ(1, app_browser->tab_strip_model()->count()); 1733 1734 // The normal browser should now have three. 1735 EXPECT_EQ(3, browser()->tab_strip_model()->count()); 1736 1737 // Open an app frame popup browser with a single blank foreground tab. 1738 Browser* app_popup_browser = new Browser(Browser::CreateParams::CreateForApp( 1739 L"Test", browser()->profile(), false)); 1740 chrome::AddBlankTabAt(app_popup_browser, -1, true); 1741 EXPECT_EQ(1, app_popup_browser->tab_strip_model()->count()); 1742 1743 // Now try opening another tab in the app popup browser. 1744 AddTabWithURLParams params3(GURL(content::kAboutBlankURL), 1745 content::PAGE_TRANSITION_TYPED); 1746 app_popup_browser->AddTabWithURL(¶ms3); 1747 EXPECT_EQ(app_popup_browser, params3.target); 1748 1749 // The popup should still only have one tab. 1750 EXPECT_EQ(1, app_popup_browser->tab_strip_model()->count()); 1751 1752 // The normal browser should now have four. 1753 EXPECT_EQ(4, browser()->tab_strip_model()->count()); 1754 1755 // Close the additional browsers. 1756 popup_browser->tab_strip_model()->CloseAllTabs(); 1757 app_browser->tab_strip_model()->CloseAllTabs(); 1758 app_popup_browser->tab_strip_model()->CloseAllTabs(); 1759} 1760#endif 1761 1762IN_PROC_BROWSER_TEST_F(BrowserTest, WindowOpenClose) { 1763 CommandLine::ForCurrentProcess()->AppendSwitch( 1764 switches::kDisablePopupBlocking); 1765 GURL url = ui_test_utils::GetTestUrl( 1766 base::FilePath(), base::FilePath().AppendASCII("window.close.html")); 1767 1768 string16 title = ASCIIToUTF16("Title Of Awesomeness"); 1769 content::TitleWatcher title_watcher( 1770 browser()->tab_strip_model()->GetActiveWebContents(), title); 1771 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url, 2); 1772 EXPECT_EQ(title, title_watcher.WaitAndGetTitle()); 1773} 1774 1775// GTK doesn't use the Browser's fullscreen state. 1776// TODO(linux_aura) http://crbug.com/163931 1777// Mac disabled: http://crbug.com/169820 1778#if !defined(TOOLKIT_GTK) && !defined(OS_MACOSX) && \ 1779 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)) 1780IN_PROC_BROWSER_TEST_F(BrowserTest, FullscreenBookmarkBar) { 1781#if defined(OS_WIN) && defined(USE_ASH) 1782 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 1783 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 1784 return; 1785#endif 1786 1787 chrome::ToggleBookmarkBar(browser()); 1788 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state()); 1789 chrome::ToggleFullscreenMode(browser()); 1790 EXPECT_TRUE(browser()->window()->IsFullscreen()); 1791#if defined(OS_MACOSX) 1792 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state()); 1793#elif defined(OS_CHROMEOS) 1794 // TODO(jamescook): If immersive fullscreen is disabled by default, test 1795 // for BookmarkBar::HIDDEN. 1796 EXPECT_EQ(BookmarkBar::SHOW, browser()->bookmark_bar_state()); 1797#else 1798 EXPECT_EQ(BookmarkBar::HIDDEN, browser()->bookmark_bar_state()); 1799#endif 1800} 1801#endif 1802 1803class ShowModalDialogTest : public BrowserTest { 1804 public: 1805 ShowModalDialogTest() {} 1806 1807 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1808 command_line->AppendSwitch(switches::kDisablePopupBlocking); 1809 } 1810}; 1811 1812IN_PROC_BROWSER_TEST_F(ShowModalDialogTest, BasicTest) { 1813 // This navigation should show a modal dialog that will be immediately 1814 // closed, but the fact that it was shown should be recorded. 1815 GURL url = ui_test_utils::GetTestUrl( 1816 base::FilePath(), base::FilePath().AppendASCII("showmodaldialog.html")); 1817 1818 string16 expected_title(ASCIIToUTF16("SUCCESS")); 1819 content::TitleWatcher title_watcher( 1820 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 1821 ui_test_utils::NavigateToURL(browser(), url); 1822 1823 // Verify that we set a mark on successful dialog show. 1824 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 1825} 1826 1827IN_PROC_BROWSER_TEST_F(BrowserTest, DisallowFileUrlUniversalAccessTest) { 1828 GURL url = ui_test_utils::GetTestUrl( 1829 base::FilePath(), 1830 base::FilePath().AppendASCII("fileurl_universalaccess.html")); 1831 1832 string16 expected_title(ASCIIToUTF16("Disallowed")); 1833 content::TitleWatcher title_watcher( 1834 browser()->tab_strip_model()->GetActiveWebContents(), expected_title); 1835 title_watcher.AlsoWaitForTitle(ASCIIToUTF16("Allowed")); 1836 ui_test_utils::NavigateToURL(browser(), url); 1837 ASSERT_EQ(expected_title, title_watcher.WaitAndGetTitle()); 1838} 1839 1840class KioskModeTest : public BrowserTest { 1841 public: 1842 KioskModeTest() {} 1843 1844 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1845 command_line->AppendSwitch(switches::kKioskMode); 1846 } 1847}; 1848 1849#if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA)) 1850// http://crbug.com/103912 1851// TODO(linux_aura) http://crbug.com/163931 1852#define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest 1853#else 1854#define MAYBE_EnableKioskModeTest EnableKioskModeTest 1855#endif 1856IN_PROC_BROWSER_TEST_F(KioskModeTest, MAYBE_EnableKioskModeTest) { 1857 // Check if browser is in fullscreen mode. 1858 ASSERT_TRUE(browser()->window()->IsFullscreen()); 1859 ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible()); 1860} 1861 1862#if defined(OS_WIN) 1863// This test verifies that Chrome can be launched with a user-data-dir path 1864// which contains non ASCII characters. 1865class LaunchBrowserWithNonAsciiUserDatadir : public BrowserTest { 1866 public: 1867 LaunchBrowserWithNonAsciiUserDatadir() {} 1868 1869 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1870 ASSERT_TRUE(temp_dir_.CreateUniqueTempDir()); 1871 base::FilePath tmp_profile = temp_dir_.path().AppendASCII("tmp_profile"); 1872 tmp_profile = tmp_profile.Append(L"Test Chrome G\u00E9raldine"); 1873 1874 ASSERT_TRUE(file_util::CreateDirectory(tmp_profile)); 1875 command_line->AppendSwitchPath(switches::kUserDataDir, tmp_profile); 1876 } 1877 1878 base::ScopedTempDir temp_dir_; 1879}; 1880 1881IN_PROC_BROWSER_TEST_F(LaunchBrowserWithNonAsciiUserDatadir, 1882 TestNonAsciiUserDataDir) { 1883 // Verify that the window is present. 1884 ASSERT_TRUE(browser()); 1885} 1886#endif // defined(OS_WIN) 1887 1888// Tests to ensure that the browser continues running in the background after 1889// the last window closes. 1890class RunInBackgroundTest : public BrowserTest { 1891 public: 1892 RunInBackgroundTest() {} 1893 1894 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1895 command_line->AppendSwitch(switches::kKeepAliveForTest); 1896 } 1897}; 1898 1899IN_PROC_BROWSER_TEST_F(RunInBackgroundTest, RunInBackgroundBasicTest) { 1900 // Close the browser window, then open a new one - the browser should keep 1901 // running. 1902 Profile* profile = browser()->profile(); 1903 EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); 1904 content::WindowedNotificationObserver observer( 1905 chrome::NOTIFICATION_BROWSER_CLOSED, 1906 content::Source<Browser>(browser())); 1907 chrome::CloseWindow(browser()); 1908 observer.Wait(); 1909 EXPECT_EQ(0u, chrome::GetTotalBrowserCount()); 1910 1911 ui_test_utils::BrowserAddedObserver browser_added_observer; 1912 chrome::NewEmptyWindow(profile, chrome::GetActiveDesktop()); 1913 browser_added_observer.WaitForSingleNewBrowser(); 1914 1915 EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); 1916} 1917 1918// Tests to ensure that the browser continues running in the background after 1919// the last window closes. 1920class NoStartupWindowTest : public BrowserTest { 1921 public: 1922 NoStartupWindowTest() {} 1923 1924 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1925 command_line->AppendSwitch(switches::kNoStartupWindow); 1926 command_line->AppendSwitch(switches::kKeepAliveForTest); 1927 } 1928}; 1929 1930IN_PROC_BROWSER_TEST_F(NoStartupWindowTest, NoStartupWindowBasicTest) { 1931#if defined(OS_WIN) && defined(USE_ASH) 1932 // kNoStartupWindow doesn't make sense in Metro+Ash. 1933 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 1934 return; 1935#endif 1936 1937 // No browser window should be started by default. 1938 EXPECT_EQ(0u, chrome::GetTotalBrowserCount()); 1939 1940 // Starting a browser window should work just fine. 1941 ui_test_utils::BrowserAddedObserver browser_added_observer; 1942 CreateBrowser(ProfileManager::GetDefaultProfile()); 1943 browser_added_observer.WaitForSingleNewBrowser(); 1944 1945 EXPECT_EQ(1u, chrome::GetTotalBrowserCount()); 1946} 1947 1948// Chromeos needs to track app windows because it considers them to be part of 1949// session state. 1950#if !defined(OS_CHROMEOS) 1951IN_PROC_BROWSER_TEST_F(NoStartupWindowTest, DontInitSessionServiceForApps) { 1952#if defined(OS_WIN) && defined(USE_ASH) 1953 // kNoStartupWindow doesn't make sense in Metro+Ash. 1954 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 1955 return; 1956#endif 1957 1958 Profile* profile = ProfileManager::GetDefaultProfile(); 1959 1960 SessionService* session_service = 1961 SessionServiceFactory::GetForProfile(profile); 1962 ASSERT_FALSE(session_service->processed_any_commands()); 1963 1964 ui_test_utils::BrowserAddedObserver browser_added_observer; 1965 CreateBrowserForApp("blah", profile); 1966 browser_added_observer.WaitForSingleNewBrowser(); 1967 1968 ASSERT_FALSE(session_service->processed_any_commands()); 1969} 1970#endif // !defined(OS_CHROMEOS) 1971 1972// This test needs to be placed outside the anonymous namespace because we 1973// need to access private type of Browser. 1974class AppModeTest : public BrowserTest { 1975 public: 1976 AppModeTest() {} 1977 1978 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE { 1979 GURL url = ui_test_utils::GetTestUrl( 1980 base::FilePath(), base::FilePath().AppendASCII("title1.html")); 1981 command_line->AppendSwitchASCII(switches::kApp, url.spec()); 1982 } 1983}; 1984 1985IN_PROC_BROWSER_TEST_F(AppModeTest, EnableAppModeTest) { 1986#if defined(OS_WIN) && defined(USE_ASH) 1987 // Disable this test in Metro+Ash for now (http://crbug.com/262796). 1988 if (CommandLine::ForCurrentProcess()->HasSwitch(switches::kAshBrowserTests)) 1989 return; 1990#endif 1991 1992 // Test that an application browser window loads correctly. 1993 1994 // Verify the browser is in application mode. 1995 EXPECT_TRUE(browser()->is_app()); 1996} 1997 1998// Confirm about:version contains some expected content. 1999IN_PROC_BROWSER_TEST_F(BrowserTest, AboutVersion) { 2000 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kAboutVersionURL)); 2001 WebContents* tab = browser()->tab_strip_model()->GetActiveWebContents(); 2002 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("WebKit"), true, true, 2003 NULL, NULL), 2004 0); 2005 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("OS"), true, true, 2006 NULL, NULL), 2007 0); 2008 ASSERT_GT(ui_test_utils::FindInPage(tab, ASCIIToUTF16("JavaScript"), true, 2009 true, NULL, NULL), 2010 0); 2011} 2012 2013static const base::FilePath::CharType* kTestDir = 2014 FILE_PATH_LITERAL("click_modifier"); 2015static const char kFirstPageTitle[] = "First window"; 2016static const char kSecondPageTitle[] = "New window!"; 2017 2018class ClickModifierTest : public InProcessBrowserTest { 2019 public: 2020 ClickModifierTest() { 2021 } 2022 2023 // Returns a url that opens a new window or tab when clicked, via javascript. 2024 GURL GetWindowOpenURL() { 2025 return ui_test_utils::GetTestUrl( 2026 base::FilePath(kTestDir), 2027 base::FilePath(FILE_PATH_LITERAL("window_open.html"))); 2028 } 2029 2030 // Returns a url that follows a simple link when clicked, unless affected by 2031 // modifiers. 2032 GURL GetHrefURL() { 2033 return ui_test_utils::GetTestUrl( 2034 base::FilePath(kTestDir), 2035 base::FilePath(FILE_PATH_LITERAL("href.html"))); 2036 } 2037 2038 string16 getFirstPageTitle() { 2039 return ASCIIToUTF16(kFirstPageTitle); 2040 } 2041 2042 string16 getSecondPageTitle() { 2043 return ASCIIToUTF16(kSecondPageTitle); 2044 } 2045 2046 // Loads our test page and simulates a single click using the supplied button 2047 // and modifiers. The click will cause either a navigation or the creation of 2048 // a new window or foreground or background tab. We verify that the expected 2049 // disposition occurs. 2050 void RunTest(Browser* browser, 2051 const GURL& url, 2052 int modifiers, 2053 WebKit::WebMouseEvent::Button button, 2054 WindowOpenDisposition disposition) { 2055 ui_test_utils::NavigateToURL(browser, url); 2056 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 2057 browser->host_desktop_type())); 2058 EXPECT_EQ(1, browser->tab_strip_model()->count()); 2059 content::WebContents* web_contents = 2060 browser->tab_strip_model()->GetActiveWebContents(); 2061 EXPECT_EQ(url, web_contents->GetURL()); 2062 2063 if (disposition == CURRENT_TAB) { 2064 content::WebContents* web_contents = 2065 browser->tab_strip_model()->GetActiveWebContents(); 2066 content::TestNavigationObserver same_tab_observer(web_contents); 2067 SimulateMouseClick(web_contents, modifiers, button); 2068 base::RunLoop run_loop; 2069 same_tab_observer.WaitForObservation( 2070 base::Bind(&content::RunThisRunLoop, base::Unretained(&run_loop)), 2071 content::GetQuitTaskForRunLoop(&run_loop)); 2072 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 2073 browser->host_desktop_type())); 2074 EXPECT_EQ(1, browser->tab_strip_model()->count()); 2075 EXPECT_EQ(getSecondPageTitle(), web_contents->GetTitle()); 2076 return; 2077 } 2078 2079 content::WindowedNotificationObserver observer( 2080 chrome::NOTIFICATION_TAB_ADDED, 2081 content::NotificationService::AllSources()); 2082 SimulateMouseClick(web_contents, modifiers, button); 2083 observer.Wait(); 2084 2085 if (disposition == NEW_WINDOW) { 2086 EXPECT_EQ(2u, chrome::GetBrowserCount(browser->profile(), 2087 browser->host_desktop_type())); 2088 return; 2089 } 2090 2091 EXPECT_EQ(1u, chrome::GetBrowserCount(browser->profile(), 2092 browser->host_desktop_type())); 2093 EXPECT_EQ(2, browser->tab_strip_model()->count()); 2094 web_contents = browser->tab_strip_model()->GetActiveWebContents(); 2095 WaitForLoadStop(web_contents); 2096 if (disposition == NEW_FOREGROUND_TAB) { 2097 EXPECT_EQ(getSecondPageTitle(), web_contents->GetTitle()); 2098 } else { 2099 ASSERT_EQ(NEW_BACKGROUND_TAB, disposition); 2100 EXPECT_EQ(getFirstPageTitle(), web_contents->GetTitle()); 2101 } 2102 } 2103 2104 private: 2105 DISALLOW_COPY_AND_ASSIGN(ClickModifierTest); 2106}; 2107 2108// Tests for clicking on elements with handlers that run window.open. 2109 2110IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenBasicClickTest) { 2111 int modifiers = 0; 2112 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2113 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2114 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2115} 2116 2117// TODO(ericu): Alt-click behavior on window.open is platform-dependent and not 2118// well defined. Should we add tests so we know if it changes? 2119 2120// Shift-clicks open in a new window. 2121IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenShiftClickTest) { 2122 int modifiers = WebKit::WebInputEvent::ShiftKey; 2123 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2124 WindowOpenDisposition disposition = NEW_WINDOW; 2125 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2126} 2127 2128// Control-clicks open in a background tab. 2129// On OSX meta [the command key] takes the place of control. 2130IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlClickTest) { 2131#if defined(OS_MACOSX) 2132 int modifiers = WebKit::WebInputEvent::MetaKey; 2133#else 2134 int modifiers = WebKit::WebInputEvent::ControlKey; 2135#endif 2136 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2137 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2138 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2139} 2140 2141// Control-shift-clicks open in a foreground tab. 2142// On OSX meta [the command key] takes the place of control. 2143IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenControlShiftClickTest) { 2144#if defined(OS_MACOSX) 2145 int modifiers = WebKit::WebInputEvent::MetaKey; 2146#else 2147 int modifiers = WebKit::WebInputEvent::ControlKey; 2148#endif 2149 modifiers |= WebKit::WebInputEvent::ShiftKey; 2150 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2151 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2152 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2153} 2154 2155// Middle-clicks open in a background tab. 2156// TODO(linux_aura) http://crbug.com/163931 2157#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 2158#define MAYBE_WindowOpenMiddleClickTest DISABLED_WindowOpenMiddleClickTest 2159#else 2160#define MAYBE_WindowOpenMiddleClickTest WindowOpenMiddleClickTest 2161#endif 2162IN_PROC_BROWSER_TEST_F(ClickModifierTest, MAYBE_WindowOpenMiddleClickTest) { 2163 int modifiers = 0; 2164 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonMiddle; 2165 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2166 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2167} 2168 2169// Shift-middle-clicks open in a foreground tab. 2170IN_PROC_BROWSER_TEST_F(ClickModifierTest, WindowOpenShiftMiddleClickTest) { 2171 int modifiers = WebKit::WebInputEvent::ShiftKey; 2172 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonMiddle; 2173 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2174 RunTest(browser(), GetWindowOpenURL(), modifiers, button, disposition); 2175} 2176 2177// Tests for clicking on normal links. 2178 2179IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefBasicClickTest) { 2180 int modifiers = 0; 2181 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2182 WindowOpenDisposition disposition = CURRENT_TAB; 2183 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2184} 2185 2186// TODO(ericu): Alt-click behavior on links is platform-dependent and not well 2187// defined. Should we add tests so we know if it changes? 2188 2189// Shift-clicks open in a new window. 2190IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefShiftClickTest) { 2191 int modifiers = WebKit::WebInputEvent::ShiftKey; 2192 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2193 WindowOpenDisposition disposition = NEW_WINDOW; 2194 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2195} 2196 2197// Control-clicks open in a background tab. 2198// On OSX meta [the command key] takes the place of control. 2199IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlClickTest) { 2200#if defined(OS_MACOSX) 2201 int modifiers = WebKit::WebInputEvent::MetaKey; 2202#else 2203 int modifiers = WebKit::WebInputEvent::ControlKey; 2204#endif 2205 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2206 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2207 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2208} 2209 2210// Control-shift-clicks open in a foreground tab. 2211// On OSX meta [the command key] takes the place of control. 2212IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefControlShiftClickTest) { 2213#if defined(OS_MACOSX) 2214 int modifiers = WebKit::WebInputEvent::MetaKey; 2215#else 2216 int modifiers = WebKit::WebInputEvent::ControlKey; 2217#endif 2218 modifiers |= WebKit::WebInputEvent::ShiftKey; 2219 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonLeft; 2220 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2221 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2222} 2223 2224// Middle-clicks open in a background tab. 2225// TODO(linux_aura) http://crbug.com/163931 2226#if defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA) 2227#define MAYBE_HrefMiddleClickTest DISABLED_HrefMiddleClickTest 2228#else 2229#define MAYBE_HrefMiddleClickTest HrefMiddleClickTest 2230#endif 2231IN_PROC_BROWSER_TEST_F(ClickModifierTest, MAYBE_HrefMiddleClickTest) { 2232 int modifiers = 0; 2233 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonMiddle; 2234 WindowOpenDisposition disposition = NEW_BACKGROUND_TAB; 2235 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2236} 2237 2238// Shift-middle-clicks open in a foreground tab. 2239IN_PROC_BROWSER_TEST_F(ClickModifierTest, HrefShiftMiddleClickTest) { 2240 int modifiers = WebKit::WebInputEvent::ShiftKey; 2241 WebKit::WebMouseEvent::Button button = WebKit::WebMouseEvent::ButtonMiddle; 2242 WindowOpenDisposition disposition = NEW_FOREGROUND_TAB; 2243 RunTest(browser(), GetHrefURL(), modifiers, button, disposition); 2244} 2245