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