1 // Copyright 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.
8 #include "base/command_line.h"
9 #include "base/compiler_specific.h"
10 #include "base/files/file_path.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/prefs/pref_service.h"
13 #include "base/strings/utf_string_conversions.h"
14 #include "base/sys_info.h"
15 #include "chrome/app/chrome_command_ids.h"
16 #include "chrome/browser/chrome_content_browser_client.h"
17 #include "chrome/browser/chrome_notification_types.h"
18 #include "chrome/browser/command_updater.h"
19 #include "chrome/browser/defaults.h"
20 #include "chrome/browser/devtools/devtools_window_testing.h"
21 #include "chrome/browser/extensions/extension_browsertest.h"
22 #include "chrome/browser/extensions/extension_service.h"
23 #include "chrome/browser/extensions/extension_util.h"
24 #include "chrome/browser/extensions/tab_helper.h"
25 #include "chrome/browser/first_run/first_run.h"
26 #include "chrome/browser/lifetime/application_lifetime.h"
27 #include "chrome/browser/prefs/incognito_mode_prefs.h"
28 #include "chrome/browser/profiles/profile.h"
29 #include "chrome/browser/profiles/profile_info_cache.h"
30 #include "chrome/browser/profiles/profile_manager.h"
31 #include "chrome/browser/search/search.h"
32 #include "chrome/browser/sessions/session_service_factory.h"
33 #include "chrome/browser/translate/chrome_translate_client.h"
34 #include "chrome/browser/translate/cld_data_harness.h"
35 #include "chrome/browser/translate/cld_data_harness_factory.h"
36 #include "chrome/browser/ui/browser.h"
37 #include "chrome/browser/ui/browser_command_controller.h"
38 #include "chrome/browser/ui/browser_commands.h"
39 #include "chrome/browser/ui/browser_finder.h"
40 #include "chrome/browser/ui/browser_iterator.h"
41 #include "chrome/browser/ui/browser_navigator.h"
42 #include "chrome/browser/ui/browser_tabstrip.h"
43 #include "chrome/browser/ui/browser_ui_prefs.h"
44 #include "chrome/browser/ui/browser_window.h"
45 #include "chrome/browser/ui/extensions/app_launch_params.h"
46 #include "chrome/browser/ui/extensions/application_launch.h"
47 #include "chrome/browser/ui/host_desktop.h"
48 #include "chrome/browser/ui/startup/startup_browser_creator.h"
49 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
50 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
51 #include "chrome/browser/ui/tabs/tab_strip_model.h"
52 #include "chrome/browser/web_applications/web_app.h"
53 #include "chrome/common/chrome_switches.h"
54 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
55 #include "chrome/common/pref_names.h"
56 #include "chrome/common/url_constants.h"
57 #include "chrome/grit/chromium_strings.h"
58 #include "chrome/grit/generated_resources.h"
59 #include "chrome/test/base/in_process_browser_test.h"
60 #include "chrome/test/base/test_switches.h"
61 #include "chrome/test/base/ui_test_utils.h"
62 #include "components/app_modal/app_modal_dialog.h"
63 #include "components/app_modal/app_modal_dialog_queue.h"
64 #include "components/app_modal/javascript_app_modal_dialog.h"
65 #include "components/app_modal/native_app_modal_dialog.h"
66 #include "components/content_settings/core/browser/host_content_settings_map.h"
67 #include "components/sessions/base_session_service_test_helper.h"
68 #include "components/translate/core/browser/language_state.h"
69 #include "components/translate/core/common/language_detection_details.h"
70 #include "content/public/browser/favicon_status.h"
71 #include "content/public/browser/host_zoom_map.h"
72 #include "content/public/browser/interstitial_page.h"
73 #include "content/public/browser/interstitial_page_delegate.h"
74 #include "content/public/browser/navigation_entry.h"
75 #include "content/public/browser/notification_service.h"
76 #include "content/public/browser/render_frame_host.h"
77 #include "content/public/browser/render_process_host.h"
78 #include "content/public/browser/render_view_host.h"
79 #include "content/public/browser/render_widget_host_view.h"
80 #include "content/public/browser/resource_context.h"
81 #include "content/public/browser/web_contents.h"
82 #include "content/public/browser/web_contents_observer.h"
83 #include "content/public/common/frame_navigate_params.h"
84 #include "content/public/common/renderer_preferences.h"
85 #include "content/public/common/url_constants.h"
86 #include "content/public/test/browser_test_utils.h"
87 #include "content/public/test/test_navigation_observer.h"
88 #include "extensions/browser/extension_registry.h"
89 #include "extensions/browser/extension_system.h"
90 #include "extensions/browser/uninstall_reason.h"
91 #include "extensions/common/constants.h"
92 #include "extensions/common/extension.h"
93 #include "extensions/common/extension_set.h"
94 #include "net/dns/mock_host_resolver.h"
95 #include "net/test/spawned_test_server/spawned_test_server.h"
96 #include "ui/base/l10n/l10n_util.h"
97 #include "ui/base/page_transition_types.h"
99 #if defined(OS_MACOSX)
100 #include "base/mac/scoped_nsautorelease_pool.h"
101 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
105 #include "base/i18n/rtl.h"
106 #include "chrome/browser/browser_process.h"
109 using app_modal::AppModalDialog
;
110 using app_modal::AppModalDialogQueue
;
111 using app_modal::JavaScriptAppModalDialog
;
112 using base::ASCIIToUTF16
;
113 using content::InterstitialPage
;
114 using content::HostZoomMap
;
115 using content::NavigationController
;
116 using content::NavigationEntry
;
117 using content::OpenURLParams
;
118 using content::Referrer
;
119 using content::WebContents
;
120 using content::WebContentsObserver
;
121 using extensions::Extension
;
125 const char* kBeforeUnloadHTML
=
126 "<html><head><title>beforeunload</title></head><body>"
127 "<script>window.onbeforeunload=function(e){return 'foo'}</script>"
130 const char* kOpenNewBeforeUnloadPage
=
131 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};";
133 const base::FilePath::CharType
* kBeforeUnloadFile
=
134 FILE_PATH_LITERAL("beforeunload.html");
136 const base::FilePath::CharType
* kTitle1File
= FILE_PATH_LITERAL("title1.html");
137 const base::FilePath::CharType
* kTitle2File
= FILE_PATH_LITERAL("title2.html");
139 const base::FilePath::CharType kDocRoot
[] =
140 FILE_PATH_LITERAL("chrome/test/data");
142 // Given a page title, returns the expected window caption string.
143 base::string16
WindowCaptionFromPageTitle(const base::string16
& page_title
) {
144 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
145 // On Mac or ChromeOS, we don't want to suffix the page title with
146 // the application name.
147 if (page_title
.empty())
148 return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED
);
151 if (page_title
.empty())
152 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME
);
154 return l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT
,
159 // Returns the number of active RenderProcessHosts.
160 int CountRenderProcessHosts() {
162 for (content::RenderProcessHost::iterator
i(
163 content::RenderProcessHost::AllHostsIterator());
164 !i
.IsAtEnd(); i
.Advance())
169 class MockTabStripModelObserver
: public TabStripModelObserver
{
171 MockTabStripModelObserver() : closing_count_(0) {}
173 void TabClosingAt(TabStripModel
* tab_strip_model
,
174 WebContents
* contents
,
175 int index
) override
{
179 int closing_count() const { return closing_count_
; }
184 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver
);
187 // Causes the browser to swap processes on a redirect to an HTTPS URL.
188 class TransferHttpsRedirectsContentBrowserClient
189 : public chrome::ChromeContentBrowserClient
{
191 bool ShouldSwapProcessesForRedirect(
192 content::ResourceContext
* resource_context
,
193 const GURL
& current_url
,
194 const GURL
& new_url
) override
{
195 return new_url
.SchemeIs(url::kHttpsScheme
);
199 // Used by CloseWithAppMenuOpen. Invokes CloseWindow on the supplied browser.
200 void CloseWindowCallback(Browser
* browser
) {
201 chrome::CloseWindow(browser
);
204 // Used by CloseWithAppMenuOpen. Posts a CloseWindowCallback and shows the app
206 void RunCloseWithAppMenuCallback(Browser
* browser
) {
207 // ShowAppMenu is modal under views. Schedule a task that closes the window.
208 base::MessageLoop::current()->PostTask(
209 FROM_HERE
, base::Bind(&CloseWindowCallback
, browser
));
210 chrome::ShowAppMenu(browser
);
213 #if !defined(OS_MACOSX)
214 // Used by ShouldLocationBarForXXX. Performs a navigation and then checks that
215 // the location bar visibility is as expcted.
216 void NavigateAndCheckForLocationBar(Browser
* browser
,
217 const std::string
& url_string
,
218 bool expected_visibility
) {
219 GURL
url(url_string
);
220 ui_test_utils::NavigateToURL(browser
, url
);
221 EXPECT_EQ(expected_visibility
,
222 browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
224 #endif // !defined(OS_MACOSX)
226 // Displays "INTERSTITIAL" while the interstitial is attached.
227 // (InterstitialPage can be used in a test directly, but there would be no way
228 // to visually tell if it is showing or not.)
229 class TestInterstitialPage
: public content::InterstitialPageDelegate
{
231 TestInterstitialPage(WebContents
* tab
, bool new_navigation
, const GURL
& url
) {
232 interstitial_page_
= InterstitialPage::Create(
233 tab
, new_navigation
, url
, this);
234 interstitial_page_
->Show();
236 ~TestInterstitialPage() override
{}
238 interstitial_page_
->Proceed();
241 interstitial_page_
->DontProceed();
244 std::string
GetHTMLContents() override
{ return "<h1>INTERSTITIAL</h1>"; }
247 InterstitialPage
* interstitial_page_
; // Owns us.
250 class RenderViewSizeObserver
: public content::WebContentsObserver
{
252 RenderViewSizeObserver(content::WebContents
* web_contents
,
253 BrowserWindow
* browser_window
)
254 : WebContentsObserver(web_contents
),
255 browser_window_(browser_window
) {
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
;
272 void set_wcv_resize_insets(const gfx::Size
& wcv_resize_insets
) {
273 wcv_resize_insets_
= wcv_resize_insets
;
276 // Cache the size when RenderViewHost is first created.
277 void RenderViewCreated(content::RenderViewHost
* render_view_host
) override
{
278 render_view_sizes_
[render_view_host
].rwhv_create_size
=
279 render_view_host
->GetView()->GetViewBounds().size();
282 // Enlarge WebContentsView by |wcv_resize_insets_| while the navigation entry
284 void DidStartNavigationToPendingEntry(
286 NavigationController::ReloadType reload_type
) override
{
287 if (wcv_resize_insets_
.IsEmpty())
289 // Resizing the main browser window by |wcv_resize_insets_| will
290 // automatically resize the WebContentsView by the same amount.
291 // Just resizing WebContentsView directly doesn't work on Linux, because the
292 // next automatic layout of the browser window will resize WebContentsView
293 // back to the previous size. To make it consistent, resize main browser
294 // window on all platforms.
295 gfx::Rect
bounds(browser_window_
->GetBounds());
296 gfx::Size
size(bounds
.size());
297 size
.Enlarge(wcv_resize_insets_
.width(), wcv_resize_insets_
.height());
298 bounds
.set_size(size
);
299 browser_window_
->SetBounds(bounds
);
300 // Let the message loop run so that resize actually takes effect.
301 content::RunAllPendingInMessageLoop();
304 // Cache the sizes of RenderWidgetHostView and WebContentsView when the
305 // navigation entry is committed, which is before
306 // WebContentsDelegate::DidNavigateMainFramePostCommit is called.
307 void NavigationEntryCommitted(
308 const content::LoadCommittedDetails
& details
) override
{
309 content::RenderViewHost
* rvh
= web_contents()->GetRenderViewHost();
310 render_view_sizes_
[rvh
].rwhv_commit_size
=
311 web_contents()->GetRenderWidgetHostView()->GetViewBounds().size();
312 render_view_sizes_
[rvh
].wcv_commit_size
=
313 web_contents()->GetContainerBounds().size();
318 gfx::Size rwhv_create_size
; // Size of RenderWidgetHostView when created.
319 gfx::Size rwhv_commit_size
; // Size of RenderWidgetHostView when committed.
320 gfx::Size wcv_commit_size
; // Size of WebContentsView when committed.
323 typedef std::map
<content::RenderViewHost
*, Sizes
> RenderViewSizes
;
324 RenderViewSizes render_view_sizes_
;
325 // Enlarge WebContentsView by this size insets in
326 // DidStartNavigationToPendingEntry.
327 gfx::Size wcv_resize_insets_
;
328 BrowserWindow
* browser_window_
; // Weak ptr.
330 DISALLOW_COPY_AND_ASSIGN(RenderViewSizeObserver
);
335 class BrowserTest
: public ExtensionBrowserTest
{
337 // In RTL locales wrap the page title with RTL embedding characters so that it
338 // matches the value returned by GetWindowTitle().
339 base::string16
LocaleWindowCaptionFromPageTitle(
340 const base::string16
& expected_title
) {
341 base::string16 page_title
= WindowCaptionFromPageTitle(expected_title
);
343 std::string locale
= g_browser_process
->GetApplicationLocale();
344 if (base::i18n::GetTextDirectionForLocale(locale
.c_str()) ==
345 base::i18n::RIGHT_TO_LEFT
) {
346 base::i18n::WrapStringWithLTRFormatting(&page_title
);
351 // Do we need to use the above code on POSIX as well?
356 // Returns the app extension aptly named "App Test".
357 const Extension
* GetExtension() {
358 extensions::ExtensionRegistry
* registry
=
359 extensions::ExtensionRegistry::Get(browser()->profile());
360 for (const scoped_refptr
<const extensions::Extension
>& extension
:
361 registry
->enabled_extensions()) {
362 if (extension
->name() == "App Test")
363 return extension
.get();
370 // Launch the app on a page with no title, check that the app title was set
372 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoTitle
) {
373 #if defined(OS_WIN) && defined(USE_ASH)
374 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
375 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
376 switches::kAshBrowserTests
))
380 ui_test_utils::NavigateToURL(
381 browser(), ui_test_utils::GetTestUrl(
382 base::FilePath(base::FilePath::kCurrentDirectory
),
383 base::FilePath(kTitle1File
)));
384 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")),
385 browser()->GetWindowTitleForCurrentTab());
386 base::string16 tab_title
;
387 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title
));
388 EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title
);
391 // Launch the app, navigate to a page with a title, check that the app title
392 // was set correctly.
393 IN_PROC_BROWSER_TEST_F(BrowserTest
, Title
) {
394 #if defined(OS_WIN) && defined(USE_ASH)
395 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
396 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
397 switches::kAshBrowserTests
))
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
);
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
, ui::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());
431 #if defined(OS_WIN) && !defined(NDEBUG)
432 // http://crbug.com/114859. Times out frequently on Windows.
433 #define MAYBE_ThirtyFourTabs DISABLED_ThirtyFourTabs
435 #define MAYBE_ThirtyFourTabs ThirtyFourTabs
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
)));
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 ui::PAGE_TRANSITION_TYPED
);
454 EXPECT_EQ(kTabCount
, browser()->tab_strip_model()->count());
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)
465 if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) {
466 EXPECT_GE(CountRenderProcessHosts(), kExpectedProcessCount
);
468 EXPECT_LT(CountRenderProcessHosts(), kExpectedProcessCount
);
472 // Test that a browser-initiated navigation to an aborted URL load leaves around
473 // a pending entry if we start from the NTP but not from a normal page.
474 // See http://crbug.com/355537.
475 IN_PROC_BROWSER_TEST_F(BrowserTest
, ClearPendingOnFailUnlessNTP
) {
476 ASSERT_TRUE(test_server()->Start());
477 WebContents
* web_contents
=
478 browser()->tab_strip_model()->GetActiveWebContents();
479 GURL
ntp_url(chrome::GetNewTabPageURL(browser()->profile()));
480 ui_test_utils::NavigateToURL(browser(), ntp_url
);
482 // Navigate to a 204 URL (aborts with no content) on the NTP and make sure it
483 // sticks around so that the user can edit it.
484 GURL
abort_url(test_server()->GetURL("nocontent"));
486 content::WindowedNotificationObserver
stop_observer(
487 content::NOTIFICATION_LOAD_STOP
,
488 content::Source
<NavigationController
>(
489 &web_contents
->GetController()));
490 browser()->OpenURL(OpenURLParams(abort_url
, Referrer(), CURRENT_TAB
,
491 ui::PAGE_TRANSITION_TYPED
, false));
492 stop_observer
.Wait();
493 EXPECT_TRUE(web_contents
->GetController().GetPendingEntry());
494 EXPECT_EQ(abort_url
, web_contents
->GetVisibleURL());
497 // Navigate to a real URL.
498 GURL
real_url(test_server()->GetURL("title1.html"));
499 ui_test_utils::NavigateToURL(browser(), real_url
);
500 EXPECT_EQ(real_url
, web_contents
->GetVisibleURL());
502 // Now navigating to a 204 URL should clear the pending entry.
504 content::WindowedNotificationObserver
stop_observer(
505 content::NOTIFICATION_LOAD_STOP
,
506 content::Source
<NavigationController
>(
507 &web_contents
->GetController()));
508 browser()->OpenURL(OpenURLParams(abort_url
, Referrer(), CURRENT_TAB
,
509 ui::PAGE_TRANSITION_TYPED
, false));
510 stop_observer
.Wait();
511 EXPECT_FALSE(web_contents
->GetController().GetPendingEntry());
512 EXPECT_EQ(real_url
, web_contents
->GetVisibleURL());
516 // Test for crbug.com/297289. Ensure that modal dialogs are closed when a
517 // cross-process navigation is ready to commit.
518 // Flaky test, see https://crbug.com/445155.
519 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_CrossProcessNavCancelsDialogs
) {
520 ASSERT_TRUE(test_server()->Start());
521 host_resolver()->AddRule("www.example.com", "127.0.0.1");
522 GURL
url(test_server()->GetURL("empty.html"));
523 ui_test_utils::NavigateToURL(browser(), url
);
525 // Test this with multiple alert dialogs to ensure that we can navigate away
526 // even if the renderer tries to synchronously create more.
527 // See http://crbug.com/312490.
528 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
529 contents
->GetMainFrame()->ExecuteJavaScript(
530 ASCIIToUTF16("alert('one'); alert('two');"));
531 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
532 EXPECT_TRUE(alert
->IsValid());
533 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
534 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
536 // A cross-site navigation should force the dialog to close.
537 GURL
url2("http://www.example.com/empty.html");
538 ui_test_utils::NavigateToURL(browser(), url2
);
539 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
541 // Make sure input events still work in the renderer process.
542 EXPECT_FALSE(contents
->GetRenderProcessHost()->IgnoreInputEvents());
545 // Make sure that dialogs are closed after a renderer process dies, and that
546 // subsequent navigations work. See http://crbug/com/343265.
547 IN_PROC_BROWSER_TEST_F(BrowserTest
, SadTabCancelsDialogs
) {
548 ASSERT_TRUE(test_server()->Start());
549 host_resolver()->AddRule("www.example.com", "127.0.0.1");
550 GURL
beforeunload_url(test_server()->GetURL("files/beforeunload.html"));
551 ui_test_utils::NavigateToURL(browser(), beforeunload_url
);
553 // Start a navigation to trigger the beforeunload dialog.
554 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
555 contents
->GetMainFrame()->ExecuteJavaScript(
556 ASCIIToUTF16("window.location.href = 'data:text/html,foo'"));
557 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
558 EXPECT_TRUE(alert
->IsValid());
559 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
560 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
562 // Crash the renderer process and ensure the dialog is gone.
563 content::RenderProcessHost
* child_process
= contents
->GetRenderProcessHost();
564 content::RenderProcessHostWatcher
crash_observer(
566 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
567 child_process
->Shutdown(0, false);
568 crash_observer
.Wait();
569 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
571 // Make sure subsequent navigations work.
572 GURL
url2("http://www.example.com/files/empty.html");
573 ui_test_utils::NavigateToURL(browser(), url2
);
576 // Make sure that dialogs opened by subframes are closed when the process dies.
577 // See http://crbug.com/366510.
578 IN_PROC_BROWSER_TEST_F(BrowserTest
, SadTabCancelsSubframeDialogs
) {
579 // Navigate to an iframe that opens an alert dialog.
580 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
581 contents
->GetMainFrame()->ExecuteJavaScript(
582 ASCIIToUTF16("window.location.href = 'data:text/html,"
583 "<iframe srcdoc=\"<script>alert(1)</script>\">'"));
584 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
585 EXPECT_TRUE(alert
->IsValid());
586 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
587 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
589 // Crash the renderer process and ensure the dialog is gone.
590 content::RenderProcessHost
* child_process
= contents
->GetRenderProcessHost();
591 content::RenderProcessHostWatcher
crash_observer(
593 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
594 child_process
->Shutdown(0, false);
595 crash_observer
.Wait();
596 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
598 // Make sure subsequent navigations work.
599 GURL
url2("data:text/html,foo");
600 ui_test_utils::NavigateToURL(browser(), url2
);
603 // Test for crbug.com/22004. Reloading a page with a before unload handler and
604 // then canceling the dialog should not leave the throbber spinning.
605 IN_PROC_BROWSER_TEST_F(BrowserTest
, ReloadThenCancelBeforeUnload
) {
606 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
607 ui_test_utils::NavigateToURL(browser(), url
);
609 // Navigate to another page, but click cancel in the dialog. Make sure that
610 // the throbber stops spinning.
611 chrome::Reload(browser(), CURRENT_TAB
);
612 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
613 alert
->CloseModalDialog();
615 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading());
617 // Clear the beforeunload handler so the test can easily exit.
618 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
619 ExecuteJavaScript(ASCIIToUTF16("onbeforeunload=null;"));
622 class RedirectObserver
: public content::WebContentsObserver
{
624 explicit RedirectObserver(content::WebContents
* web_contents
)
625 : WebContentsObserver(web_contents
) {
628 void DidNavigateAnyFrame(
629 content::RenderFrameHost
* render_frame_host
,
630 const content::LoadCommittedDetails
& details
,
631 const content::FrameNavigateParams
& params
) override
{
635 void WebContentsDestroyed() override
{
636 // Make sure we don't close the tab while the observer is in scope.
637 // See http://crbug.com/314036.
638 FAIL() << "WebContents closed during navigation (http://crbug.com/314036).";
641 const content::FrameNavigateParams
& params() const {
646 content::FrameNavigateParams params_
;
648 DISALLOW_COPY_AND_ASSIGN(RedirectObserver
);
651 // Ensure that a transferred cross-process navigation does not generate
652 // DidStopLoading events until the navigation commits. If it did, then
653 // ui_test_utils::NavigateToURL would proceed before the URL had committed.
654 // http://crbug.com/243957.
655 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoStopDuringTransferUntilCommit
) {
656 // Create HTTP and HTTPS servers for a cross-site transition.
657 ASSERT_TRUE(test_server()->Start());
658 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
659 net::SpawnedTestServer::kLocalhost
,
660 base::FilePath(kDocRoot
));
661 ASSERT_TRUE(https_test_server
.Start());
663 // Temporarily replace ContentBrowserClient with one that will cause a
664 // process swap on all redirects to HTTPS URLs.
665 TransferHttpsRedirectsContentBrowserClient new_client
;
666 content::ContentBrowserClient
* old_client
=
667 SetBrowserClientForTesting(&new_client
);
669 GURL
init_url(test_server()->GetURL("files/title1.html"));
670 ui_test_utils::NavigateToURL(browser(), init_url
);
672 // Navigate to a same-site page that redirects, causing a transfer.
673 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
675 // Create a RedirectObserver that goes away before we close the tab.
677 RedirectObserver
redirect_observer(contents
);
678 GURL
dest_url(https_test_server
.GetURL("files/title2.html"));
679 GURL
redirect_url(test_server()->GetURL("server-redirect?" +
681 ui_test_utils::NavigateToURL(browser(), redirect_url
);
683 // We should immediately see the new committed entry.
684 EXPECT_FALSE(contents
->GetController().GetPendingEntry());
686 contents
->GetController().GetLastCommittedEntry()->GetURL());
688 // We should keep track of the original request URL, redirect chain, and
689 // page transition type during a transfer, since these are necessary for
690 // history autocomplete to work.
691 EXPECT_EQ(redirect_url
, contents
->GetController().GetLastCommittedEntry()->
692 GetOriginalRequestURL());
693 EXPECT_EQ(2U, redirect_observer
.params().redirects
.size());
694 EXPECT_EQ(redirect_url
, redirect_observer
.params().redirects
.at(0));
695 EXPECT_EQ(dest_url
, redirect_observer
.params().redirects
.at(1));
696 EXPECT_TRUE(ui::PageTransitionCoreTypeIs(
697 redirect_observer
.params().transition
, ui::PAGE_TRANSITION_TYPED
));
700 // Restore previous browser client.
701 SetBrowserClientForTesting(old_client
);
704 // Tests that a cross-process redirect will only cause the beforeunload
705 // handler to run once.
706 IN_PROC_BROWSER_TEST_F(BrowserTest
, SingleBeforeUnloadAfterRedirect
) {
707 // Create HTTP and HTTPS servers for a cross-site transition.
708 ASSERT_TRUE(test_server()->Start());
709 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
710 net::SpawnedTestServer::kLocalhost
,
711 base::FilePath(kDocRoot
));
712 ASSERT_TRUE(https_test_server
.Start());
714 // Temporarily replace ContentBrowserClient with one that will cause a
715 // process swap on all redirects to HTTPS URLs.
716 TransferHttpsRedirectsContentBrowserClient new_client
;
717 content::ContentBrowserClient
* old_client
=
718 SetBrowserClientForTesting(&new_client
);
720 // Navigate to a page with a beforeunload handler.
721 GURL
url(test_server()->GetURL("files/beforeunload.html"));
722 ui_test_utils::NavigateToURL(browser(), url
);
724 // Navigate to a URL that redirects to another process and approve the
725 // beforeunload dialog that pops up.
726 content::WindowedNotificationObserver
nav_observer(
727 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
728 content::NotificationService::AllSources());
729 GURL
https_url(https_test_server
.GetURL("files/title1.html"));
730 GURL
redirect_url(test_server()->GetURL("server-redirect?" +
732 browser()->OpenURL(OpenURLParams(redirect_url
, Referrer(), CURRENT_TAB
,
733 ui::PAGE_TRANSITION_TYPED
, false));
734 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
736 static_cast<JavaScriptAppModalDialog
*>(alert
)->is_before_unload_dialog());
737 alert
->native_dialog()->AcceptAppModalDialog();
740 // Restore previous browser client.
741 SetBrowserClientForTesting(old_client
);
744 // Test for crbug.com/80401. Canceling a before unload dialog should reset
745 // the URL to the previous page's URL.
746 IN_PROC_BROWSER_TEST_F(BrowserTest
, CancelBeforeUnloadResetsURL
) {
747 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
748 base::FilePath::kCurrentDirectory
), base::FilePath(kBeforeUnloadFile
)));
749 ui_test_utils::NavigateToURL(browser(), url
);
751 // Navigate to a page that triggers a cross-site transition.
752 ASSERT_TRUE(test_server()->Start());
753 GURL
url2(test_server()->GetURL("files/title1.html"));
754 browser()->OpenURL(OpenURLParams(
755 url2
, Referrer(), CURRENT_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
757 content::WindowedNotificationObserver
host_destroyed_observer(
758 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
,
759 content::NotificationService::AllSources());
761 // Cancel the dialog.
762 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
763 alert
->CloseModalDialog();
765 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading());
767 // Verify there are no pending history items after the dialog is cancelled.
768 // (see crbug.com/93858)
769 NavigationEntry
* entry
= browser()->tab_strip_model()->
770 GetActiveWebContents()->GetController().GetPendingEntry();
771 EXPECT_EQ(NULL
, entry
);
773 // Wait for the ShouldClose_ACK to arrive. We can detect it by waiting for
774 // the pending RVH to be destroyed.
775 host_destroyed_observer
.Wait();
776 EXPECT_EQ(url
, browser()->toolbar_model()->GetURL());
778 // Clear the beforeunload handler so the test can easily exit.
779 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
780 ExecuteJavaScript(ASCIIToUTF16("onbeforeunload=null;"));
783 // Test for crbug.com/11647. A page closed with window.close() should not have
784 // two beforeunload dialogs shown.
785 // http://crbug.com/410891
786 IN_PROC_BROWSER_TEST_F(BrowserTest
,
787 DISABLED_SingleBeforeUnloadAfterWindowClose
) {
788 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
789 ExecuteJavaScriptForTests(ASCIIToUTF16(kOpenNewBeforeUnloadPage
));
791 // Close the new window with JavaScript, which should show a single
792 // beforeunload dialog. Then show another alert, to make it easy to verify
793 // that a second beforeunload dialog isn't shown.
794 browser()->tab_strip_model()->GetWebContentsAt(0)->GetMainFrame()->
795 ExecuteJavaScriptForTests(ASCIIToUTF16("w.close(); alert('bar');"));
796 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
797 alert
->native_dialog()->AcceptAppModalDialog();
799 alert
= ui_test_utils::WaitForAppModalDialog();
800 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog
*>(alert
)->
801 is_before_unload_dialog());
802 alert
->native_dialog()->AcceptAppModalDialog();
805 // BrowserTest.BeforeUnloadVsBeforeReload times out on Windows.
806 // http://crbug.com/130411
808 #define MAYBE_BeforeUnloadVsBeforeReload DISABLED_BeforeUnloadVsBeforeReload
810 #define MAYBE_BeforeUnloadVsBeforeReload BeforeUnloadVsBeforeReload
813 // Test that when a page has an onunload handler, reloading a page shows a
814 // different dialog than navigating to a different page.
815 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_BeforeUnloadVsBeforeReload
) {
816 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
817 ui_test_utils::NavigateToURL(browser(), url
);
819 // Reload the page, and check that we get a "before reload" dialog.
820 chrome::Reload(browser(), CURRENT_TAB
);
821 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
822 EXPECT_TRUE(static_cast<JavaScriptAppModalDialog
*>(alert
)->is_reload());
824 // Cancel the reload.
825 alert
->native_dialog()->CancelAppModalDialog();
827 // Navigate to another url, and check that we get a "before unload" dialog.
828 GURL
url2(url::kAboutBlankURL
);
829 browser()->OpenURL(OpenURLParams(
830 url2
, Referrer(), CURRENT_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
832 alert
= ui_test_utils::WaitForAppModalDialog();
833 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog
*>(alert
)->is_reload());
835 // Accept the navigation so we end up on a page without a beforeunload hook.
836 alert
->native_dialog()->AcceptAppModalDialog();
839 // BeforeUnloadAtQuitWithTwoWindows is a regression test for
840 // http://crbug.com/11842. It opens two windows, one of which has a
841 // beforeunload handler and attempts to exit cleanly.
842 class BeforeUnloadAtQuitWithTwoWindows
: public InProcessBrowserTest
{
844 // This test is for testing a specific shutdown behavior. This mimics what
845 // happens in InProcessBrowserTest::RunTestOnMainThread and QuitBrowsers, but
846 // ensures that it happens through the single IDC_EXIT of the test.
847 void TearDownOnMainThread() override
{
848 // Cycle both the MessageLoop and the Cocoa runloop twice to flush out any
849 // Chrome work that generates Cocoa work. Do this twice since there are two
850 // Browsers that must be closed.
854 // Run the application event loop to completion, which will cycle the
855 // native MessagePump on all platforms.
856 base::MessageLoop::current()->PostTask(FROM_HERE
,
857 base::MessageLoop::QuitClosure());
858 base::MessageLoop::current()->Run();
860 // Take care of any remaining Cocoa work.
863 // At this point, quit should be for real now.
864 ASSERT_EQ(0u, chrome::GetTotalBrowserCount());
867 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
868 // loop. It also drains the NSAutoreleasePool.
869 void CycleRunLoops() {
870 content::RunAllPendingInMessageLoop();
871 #if defined(OS_MACOSX)
872 chrome::testing::NSRunLoopRunAllPending();
873 AutoreleasePool()->Recycle();
878 // Disabled, http://crbug.com/159214 .
879 IN_PROC_BROWSER_TEST_F(BeforeUnloadAtQuitWithTwoWindows
,
880 DISABLED_IfThisTestTimesOutItIndicatesFAILURE
) {
881 // In the first browser, set up a page that has a beforeunload handler.
882 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
883 ui_test_utils::NavigateToURL(browser(), url
);
885 // Open a second browser window at about:blank.
886 ui_test_utils::BrowserAddedObserver browser_added_observer
;
887 chrome::NewEmptyWindow(browser()->profile(), chrome::GetActiveDesktop());
888 Browser
* second_window
= browser_added_observer
.WaitForSingleNewBrowser();
889 ui_test_utils::NavigateToURL(second_window
, GURL(url::kAboutBlankURL
));
891 // Tell the application to quit. IDC_EXIT calls AttemptUserExit, which on
892 // everything but ChromeOS allows unload handlers to block exit. On that
893 // platform, though, it exits unconditionally. See the comment and bug ID
894 // in AttemptUserExit() in application_lifetime.cc.
895 #if defined(OS_CHROMEOS)
896 chrome::AttemptExit();
898 chrome::ExecuteCommand(second_window
, IDC_EXIT
);
901 // The beforeunload handler will run at exit, ensure it does, and then accept
902 // it to allow shutdown to proceed.
903 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
906 static_cast<JavaScriptAppModalDialog
*>(alert
)->is_before_unload_dialog());
907 alert
->native_dialog()->AcceptAppModalDialog();
909 // But wait there's more! If this test times out, it likely means that the
910 // browser has not been able to quit correctly, indicating there's a
911 // regression of the bug noted above.
914 // Test that scripts can fork a new renderer process for a cross-site popup,
915 // based on http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab.
916 // The script must open a new tab, set its window.opener to null, and navigate
917 // it to a cross-site URL. It should also work for meta-refreshes.
918 // See http://crbug.com/93517.
919 IN_PROC_BROWSER_TEST_F(BrowserTest
, NullOpenerRedirectForksProcess
) {
920 base::CommandLine::ForCurrentProcess()->AppendSwitch(
921 switches::kDisablePopupBlocking
);
923 // Create http and https servers for a cross-site transition.
924 ASSERT_TRUE(test_server()->Start());
925 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
926 net::SpawnedTestServer::kLocalhost
,
927 base::FilePath(kDocRoot
));
928 ASSERT_TRUE(https_test_server
.Start());
929 GURL
http_url(test_server()->GetURL("files/title1.html"));
930 GURL
https_url(https_test_server
.GetURL(std::string()));
932 // Start with an http URL.
933 ui_test_utils::NavigateToURL(browser(), http_url
);
934 WebContents
* oldtab
= browser()->tab_strip_model()->GetActiveWebContents();
935 content::RenderProcessHost
* process
= oldtab
->GetRenderProcessHost();
937 // Now open a tab to a blank page, set its opener to null, and redirect it
939 std::string redirect_popup
= "w=window.open();";
940 redirect_popup
+= "w.opener=null;";
941 redirect_popup
+= "w.document.location=\"";
942 redirect_popup
+= https_url
.spec();
943 redirect_popup
+= "\";";
945 content::WindowedNotificationObserver
popup_observer(
946 chrome::NOTIFICATION_TAB_ADDED
,
947 content::NotificationService::AllSources());
948 content::WindowedNotificationObserver
nav_observer(
949 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
950 content::NotificationService::AllSources());
951 oldtab
->GetMainFrame()->
952 ExecuteJavaScriptForTests(ASCIIToUTF16(redirect_popup
));
954 // Wait for popup window to appear and finish navigating.
955 popup_observer
.Wait();
956 ASSERT_EQ(2, browser()->tab_strip_model()->count());
957 WebContents
* newtab
= browser()->tab_strip_model()->GetActiveWebContents();
959 EXPECT_NE(oldtab
, newtab
);
961 ASSERT_TRUE(newtab
->GetController().GetLastCommittedEntry());
962 EXPECT_EQ(https_url
.spec(),
963 newtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
965 // Popup window should not be in the opener's process.
966 content::RenderProcessHost
* popup_process
=
967 newtab
->GetRenderProcessHost();
968 EXPECT_NE(process
, popup_process
);
970 // Now open a tab to a blank page, set its opener to null, and use a
971 // meta-refresh to navigate it instead.
972 std::string refresh_popup
= "w=window.open();";
973 refresh_popup
+= "w.opener=null;";
974 refresh_popup
+= "w.document.write(";
975 refresh_popup
+= "'<META HTTP-EQUIV=\"refresh\" content=\"0; url=";
976 refresh_popup
+= https_url
.spec();
977 refresh_popup
+= "\">');w.document.close();";
979 content::WindowedNotificationObserver
popup_observer2(
980 chrome::NOTIFICATION_TAB_ADDED
,
981 content::NotificationService::AllSources());
982 content::WindowedNotificationObserver
nav_observer2(
983 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
984 content::NotificationService::AllSources());
985 oldtab
->GetMainFrame()->
986 ExecuteJavaScriptForTests(ASCIIToUTF16(refresh_popup
));
988 // Wait for popup window to appear and finish navigating.
989 popup_observer2
.Wait();
990 ASSERT_EQ(3, browser()->tab_strip_model()->count());
991 WebContents
* newtab2
= browser()->tab_strip_model()->GetActiveWebContents();
992 EXPECT_TRUE(newtab2
);
993 EXPECT_NE(oldtab
, newtab2
);
994 nav_observer2
.Wait();
995 ASSERT_TRUE(newtab2
->GetController().GetLastCommittedEntry());
996 EXPECT_EQ(https_url
.spec(),
997 newtab2
->GetController().GetLastCommittedEntry()->GetURL().spec());
999 // This popup window should also not be in the opener's process.
1000 content::RenderProcessHost
* popup_process2
=
1001 newtab2
->GetRenderProcessHost();
1002 EXPECT_NE(process
, popup_process2
);
1005 // Tests that other popup navigations that do not follow the steps at
1006 // http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab will not
1007 // fork a new renderer process.
1008 IN_PROC_BROWSER_TEST_F(BrowserTest
, OtherRedirectsDontForkProcess
) {
1009 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1010 switches::kDisablePopupBlocking
);
1012 // Create http and https servers for a cross-site transition.
1013 ASSERT_TRUE(test_server()->Start());
1014 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1015 net::SpawnedTestServer::kLocalhost
,
1016 base::FilePath(kDocRoot
));
1017 ASSERT_TRUE(https_test_server
.Start());
1018 GURL
http_url(test_server()->GetURL("files/title1.html"));
1019 GURL
https_url(https_test_server
.GetURL(std::string()));
1021 // Start with an http URL.
1022 ui_test_utils::NavigateToURL(browser(), http_url
);
1023 WebContents
* oldtab
= browser()->tab_strip_model()->GetActiveWebContents();
1024 content::RenderProcessHost
* process
= oldtab
->GetRenderProcessHost();
1026 // Now open a tab to a blank page, set its opener to null, and redirect it
1028 std::string dont_fork_popup
= "w=window.open();";
1029 dont_fork_popup
+= "w.document.location=\"";
1030 dont_fork_popup
+= https_url
.spec();
1031 dont_fork_popup
+= "\";";
1033 content::WindowedNotificationObserver
popup_observer(
1034 chrome::NOTIFICATION_TAB_ADDED
,
1035 content::NotificationService::AllSources());
1036 content::WindowedNotificationObserver
nav_observer(
1037 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1038 content::NotificationService::AllSources());
1039 oldtab
->GetMainFrame()->
1040 ExecuteJavaScriptForTests(ASCIIToUTF16(dont_fork_popup
));
1042 // Wait for popup window to appear and finish navigating.
1043 popup_observer
.Wait();
1044 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1045 WebContents
* newtab
= browser()->tab_strip_model()->GetActiveWebContents();
1046 EXPECT_TRUE(newtab
);
1047 EXPECT_NE(oldtab
, newtab
);
1048 nav_observer
.Wait();
1049 ASSERT_TRUE(newtab
->GetController().GetLastCommittedEntry());
1050 EXPECT_EQ(https_url
.spec(),
1051 newtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1053 // Popup window should still be in the opener's process.
1054 content::RenderProcessHost
* popup_process
=
1055 newtab
->GetRenderProcessHost();
1056 EXPECT_EQ(process
, popup_process
);
1058 // Same thing if the current tab tries to navigate itself.
1059 std::string navigate_str
= "document.location=\"";
1060 navigate_str
+= https_url
.spec();
1061 navigate_str
+= "\";";
1063 content::WindowedNotificationObserver
nav_observer2(
1064 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1065 content::NotificationService::AllSources());
1066 oldtab
->GetMainFrame()->ExecuteJavaScriptForTests(ASCIIToUTF16(navigate_str
));
1067 nav_observer2
.Wait();
1068 ASSERT_TRUE(oldtab
->GetController().GetLastCommittedEntry());
1069 EXPECT_EQ(https_url
.spec(),
1070 oldtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1072 // Original window should still be in the original process.
1073 content::RenderProcessHost
* new_process
= newtab
->GetRenderProcessHost();
1074 EXPECT_EQ(process
, new_process
);
1077 // Test that get_process_idle_time() returns reasonable values when compared
1078 // with time deltas measured locally.
1079 IN_PROC_BROWSER_TEST_F(BrowserTest
, RenderIdleTime
) {
1080 base::TimeTicks start
= base::TimeTicks::Now();
1081 ui_test_utils::NavigateToURL(
1082 browser(), ui_test_utils::GetTestUrl(
1083 base::FilePath(base::FilePath::kCurrentDirectory
),
1084 base::FilePath(kTitle1File
)));
1085 content::RenderProcessHost::iterator
it(
1086 content::RenderProcessHost::AllHostsIterator());
1087 for (; !it
.IsAtEnd(); it
.Advance()) {
1088 base::TimeDelta renderer_td
=
1089 it
.GetCurrentValue()->GetChildProcessIdleTime();
1090 base::TimeDelta browser_td
= base::TimeTicks::Now() - start
;
1091 EXPECT_TRUE(browser_td
>= renderer_td
);
1095 // Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http
1096 // and https and disabled for chrome://, about:// etc.
1097 // TODO(pinkerton): Disable app-mode in the model until we implement it
1098 // on the Mac. http://crbug.com/13148
1099 #if !defined(OS_MACOSX)
1100 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutFile
) {
1101 CommandUpdater
* command_updater
=
1102 browser()->command_controller()->command_updater();
1104 static const base::FilePath::CharType
* kEmptyFile
=
1105 FILE_PATH_LITERAL("empty.html");
1106 GURL
file_url(ui_test_utils::GetTestUrl(base::FilePath(
1107 base::FilePath::kCurrentDirectory
), base::FilePath(kEmptyFile
)));
1108 ASSERT_TRUE(file_url
.SchemeIs(url::kFileScheme
));
1109 ui_test_utils::NavigateToURL(browser(), file_url
);
1110 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1113 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutHttp
) {
1114 CommandUpdater
* command_updater
=
1115 browser()->command_controller()->command_updater();
1117 ASSERT_TRUE(test_server()->Start());
1118 GURL
http_url(test_server()->GetURL(std::string()));
1119 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1120 ui_test_utils::NavigateToURL(browser(), http_url
);
1121 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1124 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutHttps
) {
1125 CommandUpdater
* command_updater
=
1126 browser()->command_controller()->command_updater();
1128 net::SpawnedTestServer
test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1129 net::SpawnedTestServer::kLocalhost
,
1130 base::FilePath(kDocRoot
));
1131 ASSERT_TRUE(test_server
.Start());
1132 GURL
https_url(test_server
.GetURL("/"));
1133 ASSERT_TRUE(https_url
.SchemeIs(url::kHttpsScheme
));
1134 ui_test_utils::NavigateToURL(browser(), https_url
);
1135 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1138 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutFtp
) {
1139 CommandUpdater
* command_updater
=
1140 browser()->command_controller()->command_updater();
1142 net::SpawnedTestServer
test_server(net::SpawnedTestServer::TYPE_FTP
,
1143 net::SpawnedTestServer::kLocalhost
,
1144 base::FilePath(kDocRoot
));
1145 ASSERT_TRUE(test_server
.Start());
1146 GURL
ftp_url(test_server
.GetURL(std::string()));
1147 ASSERT_TRUE(ftp_url
.SchemeIs(url::kFtpScheme
));
1148 ui_test_utils::NavigateToURL(browser(), ftp_url
);
1149 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1152 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutInvalid
) {
1153 CommandUpdater
* command_updater
=
1154 browser()->command_controller()->command_updater();
1156 // Urls that should not have shortcuts.
1157 GURL
new_tab_url(chrome::kChromeUINewTabURL
);
1158 ui_test_utils::NavigateToURL(browser(), new_tab_url
);
1159 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1161 GURL
history_url(chrome::kChromeUIHistoryURL
);
1162 ui_test_utils::NavigateToURL(browser(), history_url
);
1163 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1165 GURL
downloads_url(chrome::kChromeUIDownloadsURL
);
1166 ui_test_utils::NavigateToURL(browser(), downloads_url
);
1167 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1169 GURL
blank_url(url::kAboutBlankURL
);
1170 ui_test_utils::NavigateToURL(browser(), blank_url
);
1171 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1174 // Change a tab into an application window.
1175 // DISABLED: http://crbug.com/72310
1176 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_ConvertTabToAppShortcut
) {
1177 ASSERT_TRUE(test_server()->Start());
1178 GURL
http_url(test_server()->GetURL(std::string()));
1179 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1181 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1182 WebContents
* initial_tab
= browser()->tab_strip_model()->GetWebContentsAt(0);
1183 WebContents
* app_tab
= chrome::AddSelectedTabWithURL(
1184 browser(), http_url
, ui::PAGE_TRANSITION_TYPED
);
1185 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1186 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
1187 browser()->host_desktop_type()));
1189 // Normal tabs should accept load drops.
1190 EXPECT_TRUE(initial_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1191 EXPECT_TRUE(app_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1193 // Turn |app_tab| into a tab in an app panel.
1194 chrome::ConvertTabToAppWindow(browser(), app_tab
);
1196 // The launch should have created a new browser.
1197 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1198 browser()->host_desktop_type()));
1200 // Find the new browser.
1201 Browser
* app_browser
= NULL
;
1202 for (chrome::BrowserIterator it
; !it
.done() && !app_browser
; it
.Next()) {
1203 if (*it
!= browser())
1206 ASSERT_TRUE(app_browser
);
1208 // Check that the tab contents is in the new browser, and not in the old.
1209 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1210 ASSERT_EQ(initial_tab
, browser()->tab_strip_model()->GetWebContentsAt(0));
1212 // Check that the appliaction browser has a single tab, and that tab contains
1213 // the content that we app-ified.
1214 ASSERT_EQ(1, app_browser
->tab_strip_model()->count());
1215 ASSERT_EQ(app_tab
, app_browser
->tab_strip_model()->GetWebContentsAt(0));
1217 // Normal tabs should accept load drops.
1218 EXPECT_TRUE(initial_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1220 // The tab in an app window should not.
1221 EXPECT_FALSE(app_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1224 #endif // !defined(OS_MACOSX)
1226 // Test RenderView correctly send back favicon url for web page that redirects
1227 // to an anchor in javascript body.onload handler.
1228 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1229 DISABLED_FaviconOfOnloadRedirectToAnchorPage
) {
1230 ASSERT_TRUE(test_server()->Start());
1231 GURL
url(test_server()->GetURL("files/onload_redirect_to_anchor.html"));
1232 GURL
expected_favicon_url(test_server()->GetURL("files/test.png"));
1234 ui_test_utils::NavigateToURL(browser(), url
);
1236 NavigationEntry
* entry
= browser()->tab_strip_model()->
1237 GetActiveWebContents()->GetController().GetLastCommittedEntry();
1238 EXPECT_EQ(expected_favicon_url
.spec(), entry
->GetFavicon().url
.spec());
1241 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN)
1242 // http://crbug.com/83828. On Mac 10.6, the failure rate is 14%
1243 #define MAYBE_FaviconChange DISABLED_FaviconChange
1245 #define MAYBE_FaviconChange FaviconChange
1247 // Test that an icon can be changed from JS.
1248 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_FaviconChange
) {
1249 static const base::FilePath::CharType
* kFile
=
1250 FILE_PATH_LITERAL("onload_change_favicon.html");
1251 GURL
file_url(ui_test_utils::GetTestUrl(base::FilePath(
1252 base::FilePath::kCurrentDirectory
), base::FilePath(kFile
)));
1253 ASSERT_TRUE(file_url
.SchemeIs(url::kFileScheme
));
1254 ui_test_utils::NavigateToURL(browser(), file_url
);
1256 NavigationEntry
* entry
= browser()->tab_strip_model()->
1257 GetActiveWebContents()->GetController().GetLastCommittedEntry();
1258 static const base::FilePath::CharType
* kIcon
=
1259 FILE_PATH_LITERAL("test1.png");
1260 GURL
expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath(
1261 base::FilePath::kCurrentDirectory
), base::FilePath(kIcon
)));
1262 EXPECT_EQ(expected_favicon_url
.spec(), entry
->GetFavicon().url
.spec());
1265 // http://crbug.com/172336
1267 #define MAYBE_TabClosingWhenRemovingExtension \
1268 DISABLED_TabClosingWhenRemovingExtension
1270 #define MAYBE_TabClosingWhenRemovingExtension TabClosingWhenRemovingExtension
1272 // Makes sure TabClosing is sent when uninstalling an extension that is an app
1274 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_TabClosingWhenRemovingExtension
) {
1275 ASSERT_TRUE(test_server()->Start());
1276 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1277 GURL
url(test_server()->GetURL("empty.html"));
1278 TabStripModel
* model
= browser()->tab_strip_model();
1280 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1282 const Extension
* extension_app
= GetExtension();
1284 ui_test_utils::NavigateToURL(browser(), url
);
1286 WebContents
* app_contents
= WebContents::Create(
1287 WebContents::CreateParams(browser()->profile()));
1288 extensions::TabHelper::CreateForWebContents(app_contents
);
1289 extensions::TabHelper
* extensions_tab_helper
=
1290 extensions::TabHelper::FromWebContents(app_contents
);
1291 extensions_tab_helper
->SetExtensionApp(extension_app
);
1293 model
->AddWebContents(app_contents
, 0, ui::PageTransitionFromInt(0),
1294 TabStripModel::ADD_NONE
);
1295 model
->SetTabPinned(0, true);
1296 ui_test_utils::NavigateToURL(browser(), url
);
1298 MockTabStripModelObserver observer
;
1299 model
->AddObserver(&observer
);
1301 // Uninstall the extension and make sure TabClosing is sent.
1302 ExtensionService
* service
= extensions::ExtensionSystem::Get(
1303 browser()->profile())->extension_service();
1304 service
->UninstallExtension(GetExtension()->id(),
1305 extensions::UNINSTALL_REASON_FOR_TESTING
,
1306 base::Bind(&base::DoNothing
),
1308 EXPECT_EQ(1, observer
.closing_count());
1310 model
->RemoveObserver(&observer
);
1312 // There should only be one tab now.
1313 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1316 #if !defined(OS_MACOSX)
1317 // Open with --app-id=<id>, and see that an application tab opens by default.
1318 IN_PROC_BROWSER_TEST_F(BrowserTest
, AppIdSwitch
) {
1319 ASSERT_TRUE(test_server()->Start());
1321 // There should be one tab to start with.
1322 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1325 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1326 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1327 const Extension
* extension_app
= GetExtension();
1329 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
1330 command_line
.AppendSwitchASCII(switches::kAppId
, extension_app
->id());
1332 chrome::startup::IsFirstRun first_run
= first_run::IsChromeFirstRun() ?
1333 chrome::startup::IS_FIRST_RUN
: chrome::startup::IS_NOT_FIRST_RUN
;
1334 StartupBrowserCreatorImpl
launch(base::FilePath(), command_line
, first_run
);
1336 bool new_bookmark_apps_enabled
= extensions::util::IsNewBookmarkAppsEnabled();
1338 // If the new bookmark app flow is enabled, the app should open as an tab.
1339 // Otherwise the app should open as an app window.
1340 EXPECT_EQ(!new_bookmark_apps_enabled
,
1341 launch
.OpenApplicationWindow(browser()->profile(), NULL
));
1342 EXPECT_EQ(new_bookmark_apps_enabled
,
1343 launch
.OpenApplicationTab(browser()->profile()));
1345 // Check that a the number of browsers and tabs is correct.
1346 unsigned int expected_browsers
= 1;
1347 int expected_tabs
= 1;
1348 new_bookmark_apps_enabled
? expected_tabs
++ : expected_browsers
++;
1350 EXPECT_EQ(expected_browsers
,
1351 chrome::GetBrowserCount(browser()->profile(),
1352 browser()->host_desktop_type()));
1353 EXPECT_EQ(expected_tabs
, browser()->tab_strip_model()->count());
1356 // Open an app window and the dev tools window and ensure that the location
1357 // bar settings are correct.
1358 IN_PROC_BROWSER_TEST_F(BrowserTest
, ShouldShowLocationBar
) {
1359 ASSERT_TRUE(test_server()->Start());
1362 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1363 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1364 const Extension
* extension_app
= GetExtension();
1366 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1367 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1368 browser()->profile(), extension_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1369 NEW_WINDOW
, extensions::SOURCE_TEST
));
1370 ASSERT_TRUE(app_window
);
1372 DevToolsWindow
* devtools_window
=
1373 DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false);
1375 // The launch should have created a new app browser and a dev tools browser.
1377 chrome::GetBrowserCount(browser()->profile(),
1378 browser()->host_desktop_type()));
1380 // Find the new browsers.
1381 Browser
* app_browser
= NULL
;
1382 Browser
* dev_tools_browser
= NULL
;
1383 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1384 if (*it
== browser()) {
1386 } else if ((*it
)->app_name() == DevToolsWindow::kDevToolsApp
) {
1387 dev_tools_browser
= *it
;
1392 ASSERT_TRUE(dev_tools_browser
);
1393 ASSERT_TRUE(app_browser
);
1394 ASSERT_TRUE(app_browser
!= browser());
1397 dev_tools_browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
1399 app_browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
1401 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window
);
1404 // Check that the location bar is shown correctly for HTTP bookmark apps.
1405 IN_PROC_BROWSER_TEST_F(BrowserTest
, ShouldShowLocationBarForHTTPBookmarkApp
) {
1406 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1407 switches::kEnableNewBookmarkApps
);
1408 ASSERT_TRUE(test_server()->Start());
1410 // Load a http bookmark app.
1411 const Extension
* http_bookmark_app
= InstallExtensionWithSourceAndFlags(
1412 test_data_dir_
.AppendASCII("app/"),
1414 extensions::Manifest::INTERNAL
,
1415 extensions::Extension::FROM_BOOKMARK
);
1416 ASSERT_TRUE(http_bookmark_app
);
1418 // Launch it in a window.
1419 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1420 browser()->profile(), http_bookmark_app
,
1421 extensions::LAUNCH_CONTAINER_WINDOW
, NEW_WINDOW
,
1422 extensions::SOURCE_TEST
));
1423 ASSERT_TRUE(app_window
);
1425 // Find the new browser.
1426 Browser
* http_app_browser
= NULL
;
1427 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1428 std::string app_id
=
1429 web_app::GetExtensionIdFromApplicationName((*it
)->app_name());
1430 if (*it
== browser()) {
1432 } else if (app_id
== http_bookmark_app
->id()) {
1433 http_app_browser
= *it
;
1436 ASSERT_TRUE(http_app_browser
);
1437 ASSERT_TRUE(http_app_browser
!= browser());
1439 // Navigate to the app's launch page; the location bar should be hidden.
1440 NavigateAndCheckForLocationBar(
1441 http_app_browser
, "http://www.example.com/empty.html", false);
1443 // Navigate to another page on the same origin; the location bar should still
1445 NavigateAndCheckForLocationBar(
1446 http_app_browser
, "http://www.example.com/blah", false);
1448 // Navigate to the https version of the site; the location bar should
1449 // be hidden for both browsers.
1450 NavigateAndCheckForLocationBar(
1451 http_app_browser
, "https://www.example.com/blah", false);
1453 // Navigate to different origin; the location bar should now be visible.
1454 NavigateAndCheckForLocationBar(
1455 http_app_browser
, "http://www.foo.com/blah", true);
1457 // Navigate back to the app's origin; the location bar should now be hidden.
1458 NavigateAndCheckForLocationBar(
1459 http_app_browser
, "http://www.example.com/blah", false);
1462 // Check that the location bar is shown correctly for HTTPS bookmark apps.
1463 IN_PROC_BROWSER_TEST_F(BrowserTest
, ShouldShowLocationBarForHTTPSBookmarkApp
) {
1464 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1465 switches::kEnableNewBookmarkApps
);
1466 ASSERT_TRUE(test_server()->Start());
1468 // Load a https bookmark app.
1469 const Extension
* https_bookmark_app
= InstallExtensionWithSourceAndFlags(
1470 test_data_dir_
.AppendASCII("https_app/"),
1472 extensions::Manifest::INTERNAL
,
1473 extensions::Extension::FROM_BOOKMARK
);
1474 ASSERT_TRUE(https_bookmark_app
);
1476 // Launch it in a window.
1477 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1478 browser()->profile(), https_bookmark_app
,
1479 extensions::LAUNCH_CONTAINER_WINDOW
, NEW_WINDOW
,
1480 extensions::SOURCE_TEST
));
1481 ASSERT_TRUE(app_window
);
1483 // Find the new browser.
1484 Browser
* https_app_browser
= NULL
;
1485 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1486 std::string app_id
=
1487 web_app::GetExtensionIdFromApplicationName((*it
)->app_name());
1488 if (*it
== browser()) {
1490 } else if (app_id
== https_bookmark_app
->id()) {
1491 https_app_browser
= *it
;
1494 ASSERT_TRUE(https_app_browser
);
1495 ASSERT_TRUE(https_app_browser
!= browser());
1497 // Navigate to the app's launch page; the location bar should be hidden.
1498 NavigateAndCheckForLocationBar(
1499 https_app_browser
, "https://www.example.com/empty.html", false);
1501 // Navigate to another page on the same origin; the location bar should still
1503 NavigateAndCheckForLocationBar(
1504 https_app_browser
, "https://www.example.com/blah", false);
1506 // Navigate to the http version of the site; the location bar should
1507 // be visible for the https version as it is now on a less secure version
1509 NavigateAndCheckForLocationBar(
1510 https_app_browser
, "http://www.example.com/blah", true);
1512 // Navigate to different origin; the location bar should now be visible.
1513 NavigateAndCheckForLocationBar(
1514 https_app_browser
, "http://www.foo.com/blah", true);
1516 // Navigate back to the app's origin; the location bar should now be hidden.
1517 NavigateAndCheckForLocationBar(
1518 https_app_browser
, "https://www.example.com/blah", false);
1520 #endif // !defined(OS_MACOSX)
1522 // Open a normal browser window, a hosted app window, a legacy packaged app
1523 // window and a dev tools window, and check that the web app frame feature is
1524 // supported correctly.
1525 IN_PROC_BROWSER_TEST_F(BrowserTest
, ShouldUseWebAppFrame
) {
1526 ASSERT_TRUE(test_server()->Start());
1527 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1528 switches::kEnableWebAppFrame
);
1530 // Load a hosted app.
1531 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1532 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1533 const Extension
* hosted_app
= GetExtension();
1535 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1536 WebContents
* hosted_app_window
= OpenApplication(AppLaunchParams(
1537 browser()->profile(), hosted_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1538 NEW_WINDOW
, extensions::SOURCE_UNTRACKED
));
1539 ASSERT_TRUE(hosted_app_window
);
1541 // Load a packaged app.
1542 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("packaged_app/")));
1543 const Extension
* packaged_app
= nullptr;
1544 extensions::ExtensionRegistry
* registry
=
1545 extensions::ExtensionRegistry::Get(browser()->profile());
1546 for (const scoped_refptr
<const extensions::Extension
>& extension
:
1547 registry
->enabled_extensions()) {
1548 if (extension
->name() == "Packaged App Test")
1549 packaged_app
= extension
.get();
1551 ASSERT_TRUE(packaged_app
);
1553 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1554 WebContents
* packaged_app_window
= OpenApplication(AppLaunchParams(
1555 browser()->profile(), packaged_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1556 NEW_WINDOW
, extensions::SOURCE_UNTRACKED
));
1557 ASSERT_TRUE(packaged_app_window
);
1559 DevToolsWindow
* devtools_window
=
1560 DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false);
1562 // The launch should have created a new app browser and a dev tools browser.
1563 ASSERT_EQ(4u, chrome::GetBrowserCount(browser()->profile(),
1564 browser()->host_desktop_type()));
1566 // Find the new browsers.
1567 Browser
* hosted_app_browser
= NULL
;
1568 Browser
* packaged_app_browser
= NULL
;
1569 Browser
* dev_tools_browser
= NULL
;
1570 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1571 if (*it
== browser()) {
1573 } else if ((*it
)->app_name() == DevToolsWindow::kDevToolsApp
) {
1574 dev_tools_browser
= *it
;
1575 } else if ((*it
)->tab_strip_model()->GetActiveWebContents() ==
1576 hosted_app_window
) {
1577 hosted_app_browser
= *it
;
1579 packaged_app_browser
= *it
;
1582 ASSERT_TRUE(dev_tools_browser
);
1583 ASSERT_TRUE(hosted_app_browser
);
1584 ASSERT_TRUE(hosted_app_browser
!= browser());
1585 ASSERT_TRUE(packaged_app_browser
);
1586 ASSERT_TRUE(packaged_app_browser
!= browser());
1587 ASSERT_TRUE(packaged_app_browser
!= hosted_app_browser
);
1589 EXPECT_FALSE(browser()->SupportsWindowFeature(Browser::FEATURE_WEBAPPFRAME
));
1591 dev_tools_browser
->SupportsWindowFeature(Browser::FEATURE_WEBAPPFRAME
));
1593 browser()->host_desktop_type() == chrome::HOST_DESKTOP_TYPE_ASH
,
1594 hosted_app_browser
->SupportsWindowFeature(Browser::FEATURE_WEBAPPFRAME
));
1595 EXPECT_FALSE(packaged_app_browser
->SupportsWindowFeature(
1596 Browser::FEATURE_WEBAPPFRAME
));
1598 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window
);
1601 // Tests that the CLD (Compact Language Detection) works properly.
1602 IN_PROC_BROWSER_TEST_F(BrowserTest
, PageLanguageDetection
) {
1603 scoped_ptr
<test::CldDataHarness
> cld_data_harness
=
1604 test::CldDataHarnessFactory::Get()->CreateCldDataHarness();
1605 ASSERT_NO_FATAL_FAILURE(cld_data_harness
->Init());
1606 ASSERT_TRUE(test_server()->Start());
1608 translate::LanguageDetectionDetails details
;
1610 // Open a new tab with a page in English.
1611 AddTabAtIndex(0, GURL(test_server()->GetURL("files/english_page.html")),
1612 ui::PAGE_TRANSITION_TYPED
);
1614 WebContents
* current_web_contents
=
1615 browser()->tab_strip_model()->GetActiveWebContents();
1616 ChromeTranslateClient
* chrome_translate_client
=
1617 ChromeTranslateClient::FromWebContents(current_web_contents
);
1618 content::Source
<WebContents
> source(current_web_contents
);
1620 ui_test_utils::WindowedNotificationObserverWithDetails
<
1621 translate::LanguageDetectionDetails
>
1622 en_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1625 chrome_translate_client
->GetLanguageState().original_language());
1626 en_language_detected_signal
.Wait();
1627 EXPECT_TRUE(en_language_detected_signal
.GetDetailsFor(
1628 source
.map_key(), &details
));
1629 EXPECT_EQ("en", details
.adopted_language
);
1631 chrome_translate_client
->GetLanguageState().original_language());
1633 // Now navigate to a page in French.
1634 ui_test_utils::WindowedNotificationObserverWithDetails
<
1635 translate::LanguageDetectionDetails
>
1636 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1638 ui_test_utils::NavigateToURL(
1639 browser(), GURL(test_server()->GetURL("files/french_page.html")));
1640 fr_language_detected_signal
.Wait();
1641 details
.adopted_language
.clear();
1642 EXPECT_TRUE(fr_language_detected_signal
.GetDetailsFor(
1643 source
.map_key(), &details
));
1644 EXPECT_EQ("fr", details
.adopted_language
);
1646 chrome_translate_client
->GetLanguageState().original_language());
1649 // Chromeos defaults to restoring the last session, so this test isn't
1651 #if !defined(OS_CHROMEOS)
1652 #if defined(OS_MACOSX)
1653 // Crashy, http://crbug.com/38522
1654 #define RestorePinnedTabs DISABLED_RestorePinnedTabs
1656 // Makes sure pinned tabs are restored correctly on start.
1657 IN_PROC_BROWSER_TEST_F(BrowserTest
, RestorePinnedTabs
) {
1658 ASSERT_TRUE(test_server()->Start());
1660 // Add an pinned app tab.
1661 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1662 GURL
url(test_server()->GetURL("empty.html"));
1663 TabStripModel
* model
= browser()->tab_strip_model();
1664 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1665 const Extension
* extension_app
= GetExtension();
1666 ui_test_utils::NavigateToURL(browser(), url
);
1667 WebContents
* app_contents
= WebContents::Create(
1668 WebContents::CreateParams(browser()->profile()));
1669 extensions::TabHelper::CreateForWebContents(app_contents
);
1670 extensions::TabHelper
* extensions_tab_helper
=
1671 extensions::TabHelper::FromWebContents(app_contents
);
1672 extensions_tab_helper
->SetExtensionApp(extension_app
);
1673 model
->AddWebContents(app_contents
, 0, ui::PageTransitionFromInt(0),
1674 TabStripModel::ADD_NONE
);
1675 model
->SetTabPinned(0, true);
1676 ui_test_utils::NavigateToURL(browser(), url
);
1678 // Add a non pinned tab.
1679 chrome::NewTab(browser());
1681 // Add a pinned non-app tab.
1682 chrome::NewTab(browser());
1683 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL
));
1684 model
->SetTabPinned(2, true);
1686 // Write out the pinned tabs.
1687 PinnedTabCodec::WritePinnedTabs(browser()->profile());
1689 // Simulate launching again.
1690 base::CommandLine
dummy(base::CommandLine::NO_PROGRAM
);
1691 chrome::startup::IsFirstRun first_run
= first_run::IsChromeFirstRun() ?
1692 chrome::startup::IS_FIRST_RUN
: chrome::startup::IS_NOT_FIRST_RUN
;
1693 StartupBrowserCreatorImpl
launch(base::FilePath(), dummy
, first_run
);
1694 launch
.profile_
= browser()->profile();
1695 launch
.ProcessStartupURLs(std::vector
<GURL
>(),
1696 browser()->host_desktop_type());
1698 // The launch should have created a new browser.
1699 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1700 browser()->host_desktop_type()));
1702 // Find the new browser.
1703 Browser
* new_browser
= NULL
;
1704 for (chrome::BrowserIterator it
; !it
.done() && !new_browser
; it
.Next()) {
1705 if (*it
!= browser())
1708 ASSERT_TRUE(new_browser
);
1709 ASSERT_TRUE(new_browser
!= browser());
1711 // We should get back an additional tab for the app, and another for the
1712 // default home page.
1713 ASSERT_EQ(3, new_browser
->tab_strip_model()->count());
1715 // Make sure the state matches.
1716 TabStripModel
* new_model
= new_browser
->tab_strip_model();
1717 EXPECT_TRUE(new_model
->IsAppTab(0));
1718 EXPECT_FALSE(new_model
->IsAppTab(1));
1719 EXPECT_FALSE(new_model
->IsAppTab(2));
1721 EXPECT_TRUE(new_model
->IsTabPinned(0));
1722 EXPECT_TRUE(new_model
->IsTabPinned(1));
1723 EXPECT_FALSE(new_model
->IsTabPinned(2));
1725 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL
),
1726 new_model
->GetWebContentsAt(2)->GetURL());
1729 extensions::TabHelper::FromWebContents(
1730 new_model
->GetWebContentsAt(0))->extension_app() == extension_app
);
1732 #endif // !defined(OS_CHROMEOS)
1734 // This test verifies we don't crash when closing the last window and the app
1736 IN_PROC_BROWSER_TEST_F(BrowserTest
, CloseWithAppMenuOpen
) {
1737 if (browser_defaults::kBrowserAliveWithNoWindows
)
1740 // We need a message loop running for menus on windows.
1741 base::MessageLoop::current()->PostTask(
1742 FROM_HERE
, base::Bind(&RunCloseWithAppMenuCallback
, browser()));
1745 #if !defined(OS_MACOSX)
1746 IN_PROC_BROWSER_TEST_F(BrowserTest
, OpenAppWindowLikeNtp
) {
1747 ASSERT_TRUE(test_server()->Start());
1750 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1751 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1752 const Extension
* extension_app
= GetExtension();
1754 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1755 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1756 browser()->profile(), extension_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1757 NEW_WINDOW
, extensions::SOURCE_TEST
));
1758 ASSERT_TRUE(app_window
);
1760 // Apps launched in a window from the NTP have an extensions tab helper but
1761 // do not have extension_app set in it.
1762 ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window
));
1764 extensions::TabHelper::FromWebContents(app_window
)->extension_app());
1765 EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app
),
1766 app_window
->GetURL());
1768 // The launch should have created a new browser.
1769 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1770 browser()->host_desktop_type()));
1772 // Find the new browser.
1773 Browser
* new_browser
= NULL
;
1774 for (chrome::BrowserIterator it
; !it
.done() && !new_browser
; it
.Next()) {
1775 if (*it
!= browser())
1778 ASSERT_TRUE(new_browser
);
1779 ASSERT_TRUE(new_browser
!= browser());
1781 EXPECT_TRUE(new_browser
->is_app());
1783 // The browser's app name should include the extension's id.
1784 std::string app_name
= new_browser
->app_name_
;
1785 EXPECT_NE(app_name
.find(extension_app
->id()), std::string::npos
)
1786 << "Name " << app_name
<< " should contain id "<< extension_app
->id();
1788 #endif // !defined(OS_MACOSX)
1790 // Makes sure the browser doesn't crash when
1791 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked.
1792 IN_PROC_BROWSER_TEST_F(BrowserTest
, StartMaximized
) {
1793 Browser::Type types
[] = { Browser::TYPE_TABBED
, Browser::TYPE_POPUP
};
1794 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
1795 Browser::CreateParams
params(types
[i
], browser()->profile(),
1796 browser()->host_desktop_type());
1797 params
.initial_show_state
= ui::SHOW_STATE_MAXIMIZED
;
1798 AddBlankTabAndShow(new Browser(params
));
1802 // Aura doesn't support minimized window. crbug.com/104571.
1803 #if defined(USE_AURA)
1804 #define MAYBE_StartMinimized DISABLED_StartMinimized
1806 #define MAYBE_StartMinimized StartMinimized
1808 // Makes sure the browser doesn't crash when
1809 // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked.
1810 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_StartMinimized
) {
1811 Browser::Type types
[] = { Browser::TYPE_TABBED
, Browser::TYPE_POPUP
};
1812 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
1813 Browser::CreateParams
params(types
[i
], browser()->profile(),
1814 browser()->host_desktop_type());
1815 params
.initial_show_state
= ui::SHOW_STATE_MINIMIZED
;
1816 AddBlankTabAndShow(new Browser(params
));
1820 // Makes sure the forward button is disabled immediately when navigating
1821 // forward to a slow-to-commit page.
1822 IN_PROC_BROWSER_TEST_F(BrowserTest
, ForwardDisabledOnForward
) {
1823 GURL
blank_url(url::kAboutBlankURL
);
1824 ui_test_utils::NavigateToURL(browser(), blank_url
);
1826 ui_test_utils::NavigateToURL(
1827 browser(), ui_test_utils::GetTestUrl(
1828 base::FilePath(base::FilePath::kCurrentDirectory
),
1829 base::FilePath(kTitle1File
)));
1831 content::WindowedNotificationObserver
back_nav_load_observer(
1832 content::NOTIFICATION_LOAD_STOP
,
1833 content::Source
<NavigationController
>(
1834 &browser()->tab_strip_model()->GetActiveWebContents()->
1836 chrome::GoBack(browser(), CURRENT_TAB
);
1837 back_nav_load_observer
.Wait();
1838 CommandUpdater
* command_updater
=
1839 browser()->command_controller()->command_updater();
1840 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_FORWARD
));
1842 content::WindowedNotificationObserver
forward_nav_load_observer(
1843 content::NOTIFICATION_LOAD_STOP
,
1844 content::Source
<NavigationController
>(
1845 &browser()->tab_strip_model()->GetActiveWebContents()->
1847 chrome::GoForward(browser(), CURRENT_TAB
);
1848 // This check will happen before the navigation completes, since the browser
1849 // won't process the renderer's response until the Wait() call below.
1850 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_FORWARD
));
1851 forward_nav_load_observer
.Wait();
1854 // Makes sure certain commands are disabled when Incognito mode is forced.
1855 IN_PROC_BROWSER_TEST_F(BrowserTest
, DisableMenuItemsWhenIncognitoIsForced
) {
1856 CommandUpdater
* command_updater
=
1857 browser()->command_controller()->command_updater();
1858 // At the beginning, all commands are enabled.
1859 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1860 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1861 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1862 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1863 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1864 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1866 // Set Incognito to FORCED.
1867 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1868 IncognitoModePrefs::FORCED
);
1869 // Bookmarks & Settings commands should get disabled.
1870 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1871 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1872 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1873 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1874 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1875 // New Incognito Window command, however, should be enabled.
1876 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1878 // Create a new browser.
1879 Browser
* new_browser
=
1880 new Browser(Browser::CreateParams(
1881 browser()->profile()->GetOffTheRecordProfile(),
1882 browser()->host_desktop_type()));
1883 CommandUpdater
* new_command_updater
=
1884 new_browser
->command_controller()->command_updater();
1885 // It should have Bookmarks & Settings commands disabled by default.
1886 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1887 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(
1888 IDC_SHOW_BOOKMARK_MANAGER
));
1889 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1890 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1891 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1892 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1895 // Makes sure New Incognito Window command is disabled when Incognito mode is
1897 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1898 NoNewIncognitoWindowWhenIncognitoIsDisabled
) {
1899 CommandUpdater
* command_updater
=
1900 browser()->command_controller()->command_updater();
1901 // Set Incognito to DISABLED.
1902 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1903 IncognitoModePrefs::DISABLED
);
1904 // Make sure New Incognito Window command is disabled. All remaining commands
1905 // should be enabled.
1906 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1907 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1908 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1909 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1910 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1911 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1913 // Create a new browser.
1914 Browser
* new_browser
=
1915 new Browser(Browser::CreateParams(browser()->profile(),
1916 browser()->host_desktop_type()));
1917 CommandUpdater
* new_command_updater
=
1918 new_browser
->command_controller()->command_updater();
1919 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1920 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1921 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1922 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1923 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1924 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1927 // Makes sure Extensions and Settings commands are disabled in certain
1928 // circumstances even though normally they should stay enabled.
1929 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1930 DisableExtensionsAndSettingsWhenIncognitoIsDisabled
) {
1931 CommandUpdater
* command_updater
=
1932 browser()->command_controller()->command_updater();
1933 // Disable extensions. This should disable Extensions menu.
1934 extensions::ExtensionSystem::Get(browser()->profile())->extension_service()->
1935 set_extensions_enabled(false);
1936 // Set Incognito to DISABLED.
1937 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1938 IncognitoModePrefs::DISABLED
);
1939 // Make sure Manage Extensions command is disabled.
1940 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1941 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1942 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1943 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1944 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1946 // Create a popup (non-main-UI-type) browser. Settings command as well
1947 // as Extensions should be disabled.
1948 Browser
* popup_browser
= new Browser(
1949 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
1950 browser()->host_desktop_type()));
1951 CommandUpdater
* popup_command_updater
=
1952 popup_browser
->command_controller()->command_updater();
1953 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1954 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1955 EXPECT_TRUE(popup_command_updater
->IsCommandEnabled(
1956 IDC_SHOW_BOOKMARK_MANAGER
));
1957 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1960 // Makes sure Extensions and Settings commands are disabled in certain
1961 // circumstances even though normally they should stay enabled.
1962 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1963 DisableOptionsAndImportMenuItemsConsistently
) {
1964 // Create a popup browser.
1965 Browser
* popup_browser
= new Browser(
1966 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
1967 browser()->host_desktop_type()));
1968 CommandUpdater
* command_updater
=
1969 popup_browser
->command_controller()->command_updater();
1970 // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI.
1971 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1972 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1974 // Set Incognito to FORCED.
1975 IncognitoModePrefs::SetAvailability(popup_browser
->profile()->GetPrefs(),
1976 IncognitoModePrefs::FORCED
);
1977 // OPTIONS and IMPORT_SETTINGS are disabled when Incognito is forced.
1978 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1979 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1980 // Set Incognito to AVAILABLE.
1981 IncognitoModePrefs::SetAvailability(popup_browser
->profile()->GetPrefs(),
1982 IncognitoModePrefs::ENABLED
);
1983 // OPTIONS and IMPORT_SETTINGS are still disabled since it is a non-normal UI.
1984 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1985 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1990 void OnZoomLevelChanged(const base::Closure
& callback
,
1991 const HostZoomMap::ZoomLevelChange
& host
) {
1998 // Flakes regularly on Windows XP
1999 // http://crbug.com/146040
2000 #define MAYBE_PageZoom DISABLED_PageZoom
2002 #define MAYBE_PageZoom PageZoom
2007 int GetZoomPercent(const content::WebContents
* contents
,
2009 bool* enable_minus
) {
2011 ui_zoom::ZoomController::FromWebContents(contents
)->GetZoomPercent();
2012 *enable_plus
= percent
< contents
->GetMaximumZoomPercent();
2013 *enable_minus
= percent
> contents
->GetMinimumZoomPercent();
2019 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_PageZoom
) {
2020 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2021 bool enable_plus
, enable_minus
;
2024 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2025 new content::MessageLoopRunner
);
2026 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2027 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2028 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2029 content::HostZoomMap::GetDefaultForBrowserContext(
2030 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2031 chrome::Zoom(browser(), content::PAGE_ZOOM_IN
);
2034 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 110);
2035 EXPECT_TRUE(enable_plus
);
2036 EXPECT_TRUE(enable_minus
);
2040 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2041 new content::MessageLoopRunner
);
2042 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2043 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2044 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2045 content::HostZoomMap::GetDefaultForBrowserContext(
2046 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2047 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET
);
2050 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 100);
2051 EXPECT_TRUE(enable_plus
);
2052 EXPECT_TRUE(enable_minus
);
2056 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2057 new content::MessageLoopRunner
);
2058 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2059 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2060 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2061 content::HostZoomMap::GetDefaultForBrowserContext(
2062 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2063 chrome::Zoom(browser(), content::PAGE_ZOOM_OUT
);
2066 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 90);
2067 EXPECT_TRUE(enable_plus
);
2068 EXPECT_TRUE(enable_minus
);
2071 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET
);
2074 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCommandDisable
) {
2075 ASSERT_TRUE(test_server()->Start());
2076 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2077 GURL
url(test_server()->GetURL("empty.html"));
2078 ui_test_utils::NavigateToURL(browser(), url
);
2080 CommandUpdater
* command_updater
=
2081 browser()->command_controller()->command_updater();
2082 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2083 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2084 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2085 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2087 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2089 TestInterstitialPage
* interstitial
=
2090 new TestInterstitialPage(contents
, false, GURL());
2091 content::WaitForInterstitialAttach(contents
);
2093 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2095 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2096 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2097 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2098 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2100 // Proceed and wait for interstitial to detach. This doesn't destroy
2102 interstitial
->Proceed();
2103 content::WaitForInterstitialDetach(contents
);
2104 // interstitial is deleted now.
2106 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2107 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2108 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2109 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2112 // Ensure that creating an interstitial page closes any JavaScript dialogs
2113 // that were present on the previous page. See http://crbug.com/295695.
2114 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialClosesDialogs
) {
2115 ASSERT_TRUE(test_server()->Start());
2116 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2117 GURL
url(test_server()->GetURL("empty.html"));
2118 ui_test_utils::NavigateToURL(browser(), url
);
2120 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2121 contents
->GetMainFrame()->ExecuteJavaScript(
2122 ASCIIToUTF16("alert('Dialog showing!');"));
2123 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
2124 EXPECT_TRUE(alert
->IsValid());
2125 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
2126 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
2128 TestInterstitialPage
* interstitial
=
2129 new TestInterstitialPage(contents
, false, GURL());
2130 content::WaitForInterstitialAttach(contents
);
2132 // The interstitial should have closed the dialog.
2133 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2134 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
2136 // Don't proceed and wait for interstitial to detach. This doesn't destroy
2138 interstitial
->DontProceed();
2139 content::WaitForInterstitialDetach(contents
);
2140 // interstitial is deleted now.
2142 // Make sure input events still work in the renderer process.
2143 EXPECT_FALSE(contents
->GetRenderProcessHost()->IgnoreInputEvents());
2147 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCloseTab
) {
2148 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2150 // Interstitial will delete itself when we close the tab.
2151 new TestInterstitialPage(contents
, false, GURL());
2152 content::WaitForInterstitialAttach(contents
);
2154 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2156 // Close the tab and wait for interstitial detach. This destroys |contents|.
2157 content::RunTaskAndWaitForInterstitialDetach(
2158 contents
, base::Bind(&chrome::CloseTab
, browser()));
2159 // interstitial is deleted now.
2162 class MockWebContentsObserver
: public WebContentsObserver
{
2164 explicit MockWebContentsObserver(WebContents
* web_contents
)
2165 : WebContentsObserver(web_contents
),
2166 got_user_gesture_(false) {
2169 void DidGetUserGesture() override
{ got_user_gesture_
= true; }
2171 bool got_user_gesture() const {
2172 return got_user_gesture_
;
2175 void set_got_user_gesture(bool got_it
) {
2176 got_user_gesture_
= got_it
;
2180 bool got_user_gesture_
;
2182 DISALLOW_COPY_AND_ASSIGN(MockWebContentsObserver
);
2185 IN_PROC_BROWSER_TEST_F(BrowserTest
, UserGesturesReported
) {
2186 // Regression test for http://crbug.com/110707. Also tests that a user
2187 // gesture is sent when a normal navigation (via e.g. the omnibox) is
2189 WebContents
* web_contents
=
2190 browser()->tab_strip_model()->GetActiveWebContents();
2191 MockWebContentsObserver
mock_observer(web_contents
);
2193 ASSERT_TRUE(test_server()->Start());
2194 GURL
url(test_server()->GetURL("empty.html"));
2196 ui_test_utils::NavigateToURL(browser(), url
);
2197 EXPECT_TRUE(mock_observer
.got_user_gesture());
2199 mock_observer
.set_got_user_gesture(false);
2200 chrome::Reload(browser(), CURRENT_TAB
);
2201 EXPECT_TRUE(mock_observer
.got_user_gesture());
2204 // TODO(ben): this test was never enabled. It has bit-rotted since being added.
2205 // It originally lived in browser_unittest.cc, but has been moved here to make
2206 // room for real browser unit tests.
2208 class BrowserTest2
: public InProcessBrowserTest
{
2211 host_resolver_proc_
= new net::RuleBasedHostResolverProc(NULL
);
2212 // Avoid making external DNS lookups. In this test we don't need this
2214 host_resolver_proc_
->AddSimulatedFailure("*.google.com");
2215 scoped_host_resolver_proc_
.Init(host_resolver_proc_
.get());
2219 scoped_refptr
<net::RuleBasedHostResolverProc
> host_resolver_proc_
;
2220 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_
;
2223 IN_PROC_BROWSER_TEST_F(BrowserTest2
, NoTabsInPopups
) {
2224 chrome::RegisterAppPrefs(L
"Test");
2226 // We start with a normal browser with one tab.
2227 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2229 // Open a popup browser with a single blank foreground tab.
2230 Browser
* popup_browser
= new Browser(
2231 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile()));
2232 chrome::AddTabAt(popup_browser
, GURL(), -1, true);
2233 EXPECT_EQ(1, popup_browser
->tab_strip_model()->count());
2235 // Now try opening another tab in the popup browser.
2236 AddTabWithURLParams
params1(url
, ui::PAGE_TRANSITION_TYPED
);
2237 popup_browser
->AddTabWithURL(¶ms1
);
2238 EXPECT_EQ(popup_browser
, params1
.target
);
2240 // The popup should still only have one tab.
2241 EXPECT_EQ(1, popup_browser
->tab_strip_model()->count());
2243 // The normal browser should now have two.
2244 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2246 // Open an app frame browser with a single blank foreground tab.
2247 Browser
* app_browser
= new Browser(Browser::CreateParams::CreateForApp(
2248 L
"Test", browser()->profile(), false));
2249 chrome::AddTabAt(app_browser
, GURL(), -1, true);
2250 EXPECT_EQ(1, app_browser
->tab_strip_model()->count());
2252 // Now try opening another tab in the app browser.
2253 AddTabWithURLParams
params2(GURL(url::kAboutBlankURL
),
2254 ui::PAGE_TRANSITION_TYPED
);
2255 app_browser
->AddTabWithURL(¶ms2
);
2256 EXPECT_EQ(app_browser
, params2
.target
);
2258 // The popup should still only have one tab.
2259 EXPECT_EQ(1, app_browser
->tab_strip_model()->count());
2261 // The normal browser should now have three.
2262 EXPECT_EQ(3, browser()->tab_strip_model()->count());
2264 // Open an app frame popup browser with a single blank foreground tab.
2265 Browser
* app_popup_browser
= new Browser(Browser::CreateParams::CreateForApp(
2266 L
"Test", browser()->profile(), false));
2267 chrome::AddTabAt(app_popup_browser
, GURL(), -1, true);
2268 EXPECT_EQ(1, app_popup_browser
->tab_strip_model()->count());
2270 // Now try opening another tab in the app popup browser.
2271 AddTabWithURLParams
params3(GURL(url::kAboutBlankURL
),
2272 ui::PAGE_TRANSITION_TYPED
);
2273 app_popup_browser
->AddTabWithURL(¶ms3
);
2274 EXPECT_EQ(app_popup_browser
, params3
.target
);
2276 // The popup should still only have one tab.
2277 EXPECT_EQ(1, app_popup_browser
->tab_strip_model()->count());
2279 // The normal browser should now have four.
2280 EXPECT_EQ(4, browser()->tab_strip_model()->count());
2282 // Close the additional browsers.
2283 popup_browser
->tab_strip_model()->CloseAllTabs();
2284 app_browser
->tab_strip_model()->CloseAllTabs();
2285 app_popup_browser
->tab_strip_model()->CloseAllTabs();
2289 IN_PROC_BROWSER_TEST_F(BrowserTest
, WindowOpenClose
) {
2290 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2291 switches::kDisablePopupBlocking
);
2292 GURL url
= ui_test_utils::GetTestUrl(
2293 base::FilePath(), base::FilePath().AppendASCII("window.close.html"));
2295 base::string16 title
= ASCIIToUTF16("Title Of Awesomeness");
2296 content::TitleWatcher
title_watcher(
2297 browser()->tab_strip_model()->GetActiveWebContents(), title
);
2298 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url
, 2);
2299 EXPECT_EQ(title
, title_watcher
.WaitAndGetTitle());
2302 // TODO(linux_aura) http://crbug.com/163931
2303 // Mac disabled: http://crbug.com/169820
2304 #if !defined(OS_MACOSX) && \
2305 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
2306 IN_PROC_BROWSER_TEST_F(BrowserTest
, FullscreenBookmarkBar
) {
2307 #if defined(OS_WIN) && defined(USE_ASH)
2308 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2309 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2310 switches::kAshBrowserTests
))
2314 chrome::ToggleBookmarkBar(browser());
2315 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2316 chrome::ToggleFullscreenMode(browser());
2317 EXPECT_TRUE(browser()->window()->IsFullscreen());
2318 #if defined(OS_MACOSX)
2319 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2320 #elif defined(OS_CHROMEOS)
2321 // TODO(jamescook): If immersive fullscreen is disabled by default, test
2322 // for BookmarkBar::HIDDEN.
2323 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2325 EXPECT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2330 IN_PROC_BROWSER_TEST_F(BrowserTest
, DisallowFileUrlUniversalAccessTest
) {
2331 GURL url
= ui_test_utils::GetTestUrl(
2333 base::FilePath().AppendASCII("fileurl_universalaccess.html"));
2335 base::string16
expected_title(ASCIIToUTF16("Disallowed"));
2336 content::TitleWatcher
title_watcher(
2337 browser()->tab_strip_model()->GetActiveWebContents(), expected_title
);
2338 title_watcher
.AlsoWaitForTitle(ASCIIToUTF16("Allowed"));
2339 ui_test_utils::NavigateToURL(browser(), url
);
2340 ASSERT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
2343 class KioskModeTest
: public BrowserTest
{
2347 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2348 command_line
->AppendSwitch(switches::kKioskMode
);
2352 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
2353 // Mac: http://crbug.com/103912
2354 // Linux: http://crbug.com/163931
2355 #define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest
2357 #define MAYBE_EnableKioskModeTest EnableKioskModeTest
2359 IN_PROC_BROWSER_TEST_F(KioskModeTest
, MAYBE_EnableKioskModeTest
) {
2360 // Check if browser is in fullscreen mode.
2361 ASSERT_TRUE(browser()->window()->IsFullscreen());
2362 ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible());
2366 // This test verifies that Chrome can be launched with a user-data-dir path
2367 // which contains non ASCII characters.
2368 class LaunchBrowserWithNonAsciiUserDatadir
: public BrowserTest
{
2370 LaunchBrowserWithNonAsciiUserDatadir() {}
2372 virtual void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2373 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
2374 base::FilePath tmp_profile
= temp_dir_
.path().AppendASCII("tmp_profile");
2375 tmp_profile
= tmp_profile
.Append(L
"Test Chrome G\u00E9raldine");
2377 ASSERT_TRUE(base::CreateDirectory(tmp_profile
));
2378 command_line
->AppendSwitchPath(switches::kUserDataDir
, tmp_profile
);
2381 base::ScopedTempDir temp_dir_
;
2384 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithNonAsciiUserDatadir
,
2385 TestNonAsciiUserDataDir
) {
2386 // Verify that the window is present.
2387 ASSERT_TRUE(browser());
2388 ASSERT_TRUE(browser()->profile());
2389 // Verify that the profile has been added correctly to the ProfileInfoCache.
2390 ASSERT_EQ(1u, g_browser_process
->profile_manager()->
2391 GetProfileInfoCache().GetNumberOfProfiles());
2393 #endif // defined(OS_WIN)
2396 // This test verifies that Chrome can be launched with a user-data-dir path
2397 // which trailing slashes.
2398 class LaunchBrowserWithTrailingSlashDatadir
: public BrowserTest
{
2400 LaunchBrowserWithTrailingSlashDatadir() {}
2402 virtual void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2403 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
2404 base::FilePath tmp_profile
= temp_dir_
.path().AppendASCII("tmp_profile");
2405 tmp_profile
= tmp_profile
.Append(L
"Test Chrome\\");
2407 ASSERT_TRUE(base::CreateDirectory(tmp_profile
));
2408 command_line
->AppendSwitchPath(switches::kUserDataDir
, tmp_profile
);
2411 base::ScopedTempDir temp_dir_
;
2414 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithTrailingSlashDatadir
,
2415 TestTrailingSlashUserDataDir
) {
2416 // Verify that the window is present.
2417 ASSERT_TRUE(browser());
2418 ASSERT_TRUE(browser()->profile());
2419 // Verify that the profile has been added correctly to the ProfileInfoCache.
2420 ASSERT_EQ(1u, g_browser_process
->profile_manager()->
2421 GetProfileInfoCache().GetNumberOfProfiles());
2423 #endif // defined(OS_WIN)
2425 // Tests to ensure that the browser continues running in the background after
2426 // the last window closes.
2427 class RunInBackgroundTest
: public BrowserTest
{
2429 RunInBackgroundTest() {}
2431 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2432 command_line
->AppendSwitch(switches::kKeepAliveForTest
);
2436 IN_PROC_BROWSER_TEST_F(RunInBackgroundTest
, RunInBackgroundBasicTest
) {
2437 // Close the browser window, then open a new one - the browser should keep
2439 Profile
* profile
= browser()->profile();
2440 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2441 content::WindowedNotificationObserver
observer(
2442 chrome::NOTIFICATION_BROWSER_CLOSED
,
2443 content::Source
<Browser
>(browser()));
2444 chrome::CloseWindow(browser());
2446 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2448 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2449 chrome::NewEmptyWindow(profile
, chrome::GetActiveDesktop());
2450 browser_added_observer
.WaitForSingleNewBrowser();
2452 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2455 // Tests to ensure that the browser continues running in the background after
2456 // the last window closes.
2457 class NoStartupWindowTest
: public BrowserTest
{
2459 NoStartupWindowTest() {}
2461 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2462 command_line
->AppendSwitch(switches::kNoStartupWindow
);
2463 command_line
->AppendSwitch(switches::kKeepAliveForTest
);
2466 // Returns true if any commands were processed.
2467 bool ProcessedAnyCommands(
2468 sessions::BaseSessionService
* base_session_service
) {
2469 sessions::BaseSessionServiceTestHelper
test_helper(base_session_service
);
2470 return test_helper
.ProcessedAnyCommands();
2474 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest
, NoStartupWindowBasicTest
) {
2475 #if defined(OS_WIN) && defined(USE_ASH)
2476 // kNoStartupWindow doesn't make sense in Metro+Ash.
2477 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2478 switches::kAshBrowserTests
))
2482 // No browser window should be started by default.
2483 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2485 // Starting a browser window should work just fine.
2486 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2487 CreateBrowser(ProfileManager::GetActiveUserProfile());
2488 browser_added_observer
.WaitForSingleNewBrowser();
2490 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2493 // Chromeos needs to track app windows because it considers them to be part of
2495 #if !defined(OS_CHROMEOS)
2496 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest
, DontInitSessionServiceForApps
) {
2497 #if defined(OS_WIN) && defined(USE_ASH)
2498 // kNoStartupWindow doesn't make sense in Metro+Ash.
2499 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2500 switches::kAshBrowserTests
))
2504 Profile
* profile
= ProfileManager::GetActiveUserProfile();
2506 SessionService
* session_service
=
2507 SessionServiceFactory::GetForProfile(profile
);
2508 sessions::BaseSessionService
* base_session_service
=
2509 session_service
->GetBaseSessionServiceForTest();
2510 ASSERT_FALSE(ProcessedAnyCommands(base_session_service
));
2512 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2513 CreateBrowserForApp("blah", profile
);
2514 browser_added_observer
.WaitForSingleNewBrowser();
2516 ASSERT_FALSE(ProcessedAnyCommands(base_session_service
));
2518 #endif // !defined(OS_CHROMEOS)
2520 // This test needs to be placed outside the anonymous namespace because we
2521 // need to access private type of Browser.
2522 class AppModeTest
: public BrowserTest
{
2526 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2527 GURL url
= ui_test_utils::GetTestUrl(
2528 base::FilePath(), base::FilePath().AppendASCII("title1.html"));
2529 command_line
->AppendSwitchASCII(switches::kApp
, url
.spec());
2533 IN_PROC_BROWSER_TEST_F(AppModeTest
, EnableAppModeTest
) {
2534 #if defined(OS_WIN) && defined(USE_ASH)
2535 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2536 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2537 switches::kAshBrowserTests
))
2541 // Test that an application browser window loads correctly.
2543 // Verify the browser is in application mode.
2544 EXPECT_TRUE(browser()->is_app());
2547 // Confirm chrome://version contains some expected content.
2548 IN_PROC_BROWSER_TEST_F(BrowserTest
, AboutVersion
) {
2549 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL
));
2550 WebContents
* tab
= browser()->tab_strip_model()->GetActiveWebContents();
2551 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("WebKit"), true, true,
2554 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("OS"), true, true,
2557 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("JavaScript"), true,
2562 static const base::FilePath::CharType
* kTestDir
=
2563 FILE_PATH_LITERAL("click_modifier");
2564 static const char kFirstPageTitle
[] = "First window";
2565 static const char kSecondPageTitle
[] = "New window!";
2567 class ClickModifierTest
: public InProcessBrowserTest
{
2569 ClickModifierTest() {
2572 // Returns a url that opens a new window or tab when clicked, via javascript.
2573 GURL
GetWindowOpenURL() {
2574 return ui_test_utils::GetTestUrl(
2575 base::FilePath(kTestDir
),
2576 base::FilePath(FILE_PATH_LITERAL("window_open.html")));
2579 // Returns a url that follows a simple link when clicked, unless affected by
2582 return ui_test_utils::GetTestUrl(
2583 base::FilePath(kTestDir
),
2584 base::FilePath(FILE_PATH_LITERAL("href.html")));
2587 base::string16
getFirstPageTitle() {
2588 return ASCIIToUTF16(kFirstPageTitle
);
2591 base::string16
getSecondPageTitle() {
2592 return ASCIIToUTF16(kSecondPageTitle
);
2595 // Loads our test page and simulates a single click using the supplied button
2596 // and modifiers. The click will cause either a navigation or the creation of
2597 // a new window or foreground or background tab. We verify that the expected
2598 // disposition occurs.
2599 void RunTest(Browser
* browser
,
2602 blink::WebMouseEvent::Button button
,
2603 WindowOpenDisposition disposition
) {
2604 ui_test_utils::NavigateToURL(browser
, url
);
2605 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2606 browser
->host_desktop_type()));
2607 EXPECT_EQ(1, browser
->tab_strip_model()->count());
2608 content::WebContents
* web_contents
=
2609 browser
->tab_strip_model()->GetActiveWebContents();
2610 EXPECT_EQ(url
, web_contents
->GetURL());
2612 if (disposition
== CURRENT_TAB
) {
2613 content::WebContents
* web_contents
=
2614 browser
->tab_strip_model()->GetActiveWebContents();
2615 content::TestNavigationObserver
same_tab_observer(web_contents
);
2616 SimulateMouseClick(web_contents
, modifiers
, button
);
2617 same_tab_observer
.Wait();
2618 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2619 browser
->host_desktop_type()));
2620 EXPECT_EQ(1, browser
->tab_strip_model()->count());
2621 EXPECT_EQ(getSecondPageTitle(), web_contents
->GetTitle());
2625 content::WindowedNotificationObserver
observer(
2626 chrome::NOTIFICATION_TAB_ADDED
,
2627 content::NotificationService::AllSources());
2628 SimulateMouseClick(web_contents
, modifiers
, button
);
2631 if (disposition
== NEW_WINDOW
) {
2632 EXPECT_EQ(2u, chrome::GetBrowserCount(browser
->profile(),
2633 browser
->host_desktop_type()));
2637 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2638 browser
->host_desktop_type()));
2639 EXPECT_EQ(2, browser
->tab_strip_model()->count());
2640 web_contents
= browser
->tab_strip_model()->GetActiveWebContents();
2641 WaitForLoadStop(web_contents
);
2642 if (disposition
== NEW_FOREGROUND_TAB
) {
2643 EXPECT_EQ(getSecondPageTitle(), web_contents
->GetTitle());
2645 ASSERT_EQ(NEW_BACKGROUND_TAB
, disposition
);
2646 EXPECT_EQ(getFirstPageTitle(), web_contents
->GetTitle());
2651 DISALLOW_COPY_AND_ASSIGN(ClickModifierTest
);
2654 // Tests for clicking on elements with handlers that run window.open.
2656 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenBasicClickTest
) {
2658 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2659 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2660 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2663 // TODO(ericu): Alt-click behavior on window.open is platform-dependent and not
2664 // well defined. Should we add tests so we know if it changes?
2666 // Shift-clicks open in a new window.
2667 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenShiftClickTest
) {
2668 int modifiers
= blink::WebInputEvent::ShiftKey
;
2669 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2670 WindowOpenDisposition disposition
= NEW_WINDOW
;
2671 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2674 // Control-clicks open in a background tab.
2675 // On OSX meta [the command key] takes the place of control.
2676 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenControlClickTest
) {
2677 #if defined(OS_MACOSX)
2678 int modifiers
= blink::WebInputEvent::MetaKey
;
2680 int modifiers
= blink::WebInputEvent::ControlKey
;
2682 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2683 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2684 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2687 // Control-shift-clicks open in a foreground tab.
2688 // On OSX meta [the command key] takes the place of control.
2689 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenControlShiftClickTest
) {
2690 #if defined(OS_MACOSX)
2691 int modifiers
= blink::WebInputEvent::MetaKey
;
2693 int modifiers
= blink::WebInputEvent::ControlKey
;
2695 modifiers
|= blink::WebInputEvent::ShiftKey
;
2696 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2697 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2698 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2701 // Middle-clicks open in a background tab.
2702 #if defined(OS_LINUX)
2703 // http://crbug.com/396347
2704 #define MAYBE_WindowOpenMiddleClickTest DISABLED_WindowOpenMiddleClickTest
2706 #define MAYBE_WindowOpenMiddleClickTest WindowOpenMiddleClickTest
2708 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, MAYBE_WindowOpenMiddleClickTest
) {
2710 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2711 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2712 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2715 // Shift-middle-clicks open in a foreground tab.
2716 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenShiftMiddleClickTest
) {
2717 int modifiers
= blink::WebInputEvent::ShiftKey
;
2718 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2719 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2720 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2723 // Tests for clicking on normal links.
2725 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefBasicClickTest
) {
2727 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2728 WindowOpenDisposition disposition
= CURRENT_TAB
;
2729 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2732 // TODO(ericu): Alt-click behavior on links is platform-dependent and not well
2733 // defined. Should we add tests so we know if it changes?
2735 // Shift-clicks open in a new window.
2736 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefShiftClickTest
) {
2737 int modifiers
= blink::WebInputEvent::ShiftKey
;
2738 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2739 WindowOpenDisposition disposition
= NEW_WINDOW
;
2740 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2743 // Control-clicks open in a background tab.
2744 // On OSX meta [the command key] takes the place of control.
2745 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefControlClickTest
) {
2746 #if defined(OS_MACOSX)
2747 int modifiers
= blink::WebInputEvent::MetaKey
;
2749 int modifiers
= blink::WebInputEvent::ControlKey
;
2751 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2752 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2753 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2756 // Control-shift-clicks open in a foreground tab.
2757 // On OSX meta [the command key] takes the place of control.
2758 // http://crbug.com/396347
2759 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, DISABLED_HrefControlShiftClickTest
) {
2760 #if defined(OS_MACOSX)
2761 int modifiers
= blink::WebInputEvent::MetaKey
;
2763 int modifiers
= blink::WebInputEvent::ControlKey
;
2765 modifiers
|= blink::WebInputEvent::ShiftKey
;
2766 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2767 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2768 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2771 // Middle-clicks open in a background tab.
2772 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefMiddleClickTest
) {
2774 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2775 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2776 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2779 // Shift-middle-clicks open in a foreground tab.
2780 // http://crbug.com/396347
2781 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, DISABLED_HrefShiftMiddleClickTest
) {
2782 int modifiers
= blink::WebInputEvent::ShiftKey
;
2783 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2784 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2785 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2788 IN_PROC_BROWSER_TEST_F(BrowserTest
, GetSizeForNewRenderView
) {
2789 // The instant extended NTP has javascript that does not work with
2790 // ui_test_utils::NavigateToURL. The NTP rvh reloads when the browser tries
2791 // to navigate away from the page, which causes the WebContents to end up in
2792 // an inconsistent state. (is_loaded = true, last_commited_url=ntp,
2793 // visible_url=title1.html)
2794 browser()->profile()->GetPrefs()->SetBoolean(prefs::kWebKitJavascriptEnabled
,
2796 ASSERT_TRUE(test_server()->Start());
2797 // Create an HTTPS server for cross-site transition.
2798 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
2799 net::SpawnedTestServer::kLocalhost
,
2800 base::FilePath(kDocRoot
));
2801 ASSERT_TRUE(https_test_server
.Start());
2804 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2805 ASSERT_EQ(BookmarkBar::DETACHED
, browser()->bookmark_bar_state());
2806 WebContents
* web_contents
=
2807 browser()->tab_strip_model()->GetActiveWebContents();
2808 content::RenderViewHost
* prev_rvh
= web_contents
->GetRenderViewHost();
2809 const int height_inset
=
2810 browser()->window()->GetRenderViewHeightInsetWithDetachedBookmarkBar();
2811 const gfx::Size initial_wcv_size
=
2812 web_contents
->GetContainerBounds().size();
2813 RenderViewSizeObserver
observer(web_contents
, browser()->window());
2815 // Navigate to a non-NTP page, without resizing WebContentsView.
2816 ui_test_utils::NavigateToURL(browser(),
2817 test_server()->GetURL("files/title1.html"));
2818 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2819 // A new RenderViewHost should be created.
2820 EXPECT_NE(prev_rvh
, web_contents
->GetRenderViewHost());
2821 prev_rvh
= web_contents
->GetRenderViewHost();
2822 gfx::Size rwhv_create_size0
, rwhv_commit_size0
, wcv_commit_size0
;
2823 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2827 // The create height of RenderWidgetHostView should include the height inset.
2828 EXPECT_EQ(gfx::Size(initial_wcv_size
.width(),
2829 initial_wcv_size
.height() + height_inset
),
2831 // When a navigation entry is committed, the size of RenderWidgetHostView
2832 // should be the same as when it was first created.
2833 EXPECT_EQ(rwhv_create_size0
, rwhv_commit_size0
);
2834 // Sizes of the current RenderWidgetHostView and WebContentsView should not
2835 // change before and after WebContentsDelegate::DidNavigateMainFramePostCommit
2836 // (implemented by Browser); we obtain the sizes before PostCommit via
2837 // WebContentsObserver::NavigationEntryCommitted (implemented by
2838 // RenderViewSizeObserver).
2839 EXPECT_EQ(rwhv_commit_size0
,
2840 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2841 // The behavior differs between OSX and views.
2842 // In OSX, the wcv does not change size until after the commit, when the
2843 // bookmark bar disappears (correct).
2844 // In views, the wcv changes size at commit time.
2845 #if defined(OS_MACOSX)
2846 EXPECT_EQ(gfx::Size(wcv_commit_size0
.width(),
2847 wcv_commit_size0
.height() + height_inset
),
2848 web_contents
->GetContainerBounds().size());
2850 EXPECT_EQ(wcv_commit_size0
, web_contents
->GetContainerBounds().size());
2853 // Navigate to another non-NTP page, without resizing WebContentsView.
2854 ui_test_utils::NavigateToURL(browser(),
2855 https_test_server
.GetURL("files/title2.html"));
2856 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2857 // A new RenderVieHost should be created.
2858 EXPECT_NE(prev_rvh
, web_contents
->GetRenderViewHost());
2859 gfx::Size rwhv_create_size1
, rwhv_commit_size1
, wcv_commit_size1
;
2860 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2864 EXPECT_EQ(rwhv_create_size1
, rwhv_commit_size1
);
2865 EXPECT_EQ(rwhv_commit_size1
,
2866 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2867 EXPECT_EQ(wcv_commit_size1
, web_contents
->GetContainerBounds().size());
2869 // Navigate from NTP to a non-NTP page, resizing WebContentsView while
2870 // navigation entry is pending.
2871 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2872 gfx::Size
wcv_resize_insets(1, 1);
2873 observer
.set_wcv_resize_insets(wcv_resize_insets
);
2874 ui_test_utils::NavigateToURL(browser(),
2875 test_server()->GetURL("files/title2.html"));
2876 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2877 gfx::Size rwhv_create_size2
, rwhv_commit_size2
, wcv_commit_size2
;
2878 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2883 // The behavior on OSX and Views is incorrect in this edge case, but they are
2884 // differently incorrect.
2885 // The behavior should be:
2886 // initial wcv size: (100,100) (to choose random numbers)
2887 // initial rwhv size: (100,140)
2888 // commit wcv size: (101, 101)
2889 // commit rwhv size: (101, 141)
2890 // final wcv size: (101, 141)
2891 // final rwhv size: (101, 141)
2893 // On OSX, the commit rwhv size is (101, 101)
2894 // On views, the commit wcv size is (101, 141)
2895 // All other sizes are correct.
2897 // The create height of RenderWidgetHostView should include the height inset.
2898 EXPECT_EQ(gfx::Size(initial_wcv_size
.width(),
2899 initial_wcv_size
.height() + height_inset
),
2901 gfx::Size
exp_commit_size(initial_wcv_size
);
2903 #if defined(OS_MACOSX)
2904 exp_commit_size
.Enlarge(wcv_resize_insets
.width(),
2905 wcv_resize_insets
.height());
2907 exp_commit_size
.Enlarge(wcv_resize_insets
.width(),
2908 wcv_resize_insets
.height() + height_inset
);
2910 EXPECT_EQ(exp_commit_size
, rwhv_commit_size2
);
2911 EXPECT_EQ(exp_commit_size
, wcv_commit_size2
);
2912 gfx::Size
exp_final_size(initial_wcv_size
);
2913 exp_final_size
.Enlarge(wcv_resize_insets
.width(),
2914 wcv_resize_insets
.height() + height_inset
);
2915 EXPECT_EQ(exp_final_size
,
2916 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2917 EXPECT_EQ(exp_final_size
, web_contents
->GetContainerBounds().size());