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