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