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