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