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