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/location.h"
12 #include "base/memory/scoped_ptr.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/prefs/pref_service.h"
15 #include "base/strings/utf_string_conversions.h"
16 #include "base/sys_info.h"
17 #include "chrome/app/chrome_command_ids.h"
18 #include "chrome/browser/chrome_content_browser_client.h"
19 #include "chrome/browser/chrome_notification_types.h"
20 #include "chrome/browser/command_updater.h"
21 #include "chrome/browser/defaults.h"
22 #include "chrome/browser/devtools/devtools_window_testing.h"
23 #include "chrome/browser/extensions/extension_browsertest.h"
24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/extension_util.h"
26 #include "chrome/browser/extensions/tab_helper.h"
27 #include "chrome/browser/first_run/first_run.h"
28 #include "chrome/browser/lifetime/application_lifetime.h"
29 #include "chrome/browser/prefs/incognito_mode_prefs.h"
30 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/profiles/profile_info_cache.h"
32 #include "chrome/browser/profiles/profile_manager.h"
33 #include "chrome/browser/search/search.h"
34 #include "chrome/browser/sessions/session_service_factory.h"
35 #include "chrome/browser/ssl/connection_security.h"
36 #include "chrome/browser/translate/chrome_translate_client.h"
37 #include "chrome/browser/translate/cld_data_harness.h"
38 #include "chrome/browser/translate/cld_data_harness_factory.h"
39 #include "chrome/browser/ui/browser.h"
40 #include "chrome/browser/ui/browser_command_controller.h"
41 #include "chrome/browser/ui/browser_commands.h"
42 #include "chrome/browser/ui/browser_finder.h"
43 #include "chrome/browser/ui/browser_iterator.h"
44 #include "chrome/browser/ui/browser_navigator.h"
45 #include "chrome/browser/ui/browser_tabstrip.h"
46 #include "chrome/browser/ui/browser_ui_prefs.h"
47 #include "chrome/browser/ui/browser_window.h"
48 #include "chrome/browser/ui/extensions/app_launch_params.h"
49 #include "chrome/browser/ui/extensions/application_launch.h"
50 #include "chrome/browser/ui/host_desktop.h"
51 #include "chrome/browser/ui/startup/startup_browser_creator.h"
52 #include "chrome/browser/ui/startup/startup_browser_creator_impl.h"
53 #include "chrome/browser/ui/tabs/pinned_tab_codec.h"
54 #include "chrome/browser/ui/tabs/tab_strip_model.h"
55 #include "chrome/common/chrome_switches.h"
56 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
57 #include "chrome/common/pref_names.h"
58 #include "chrome/common/url_constants.h"
59 #include "chrome/grit/chromium_strings.h"
60 #include "chrome/grit/generated_resources.h"
61 #include "chrome/test/base/in_process_browser_test.h"
62 #include "chrome/test/base/test_switches.h"
63 #include "chrome/test/base/ui_test_utils.h"
64 #include "components/app_modal/app_modal_dialog.h"
65 #include "components/app_modal/app_modal_dialog_queue.h"
66 #include "components/app_modal/javascript_app_modal_dialog.h"
67 #include "components/app_modal/native_app_modal_dialog.h"
68 #include "components/content_settings/core/browser/host_content_settings_map.h"
69 #include "components/sessions/base_session_service_test_helper.h"
70 #include "components/translate/core/browser/language_state.h"
71 #include "components/translate/core/common/language_detection_details.h"
72 #include "content/public/browser/favicon_status.h"
73 #include "content/public/browser/host_zoom_map.h"
74 #include "content/public/browser/interstitial_page.h"
75 #include "content/public/browser/interstitial_page_delegate.h"
76 #include "content/public/browser/navigation_entry.h"
77 #include "content/public/browser/notification_service.h"
78 #include "content/public/browser/render_frame_host.h"
79 #include "content/public/browser/render_process_host.h"
80 #include "content/public/browser/render_view_host.h"
81 #include "content/public/browser/render_widget_host_view.h"
82 #include "content/public/browser/resource_context.h"
83 #include "content/public/browser/security_style_explanation.h"
84 #include "content/public/browser/security_style_explanations.h"
85 #include "content/public/browser/web_contents.h"
86 #include "content/public/browser/web_contents_observer.h"
87 #include "content/public/common/frame_navigate_params.h"
88 #include "content/public/common/renderer_preferences.h"
89 #include "content/public/common/url_constants.h"
90 #include "content/public/test/browser_test_utils.h"
91 #include "content/public/test/test_navigation_observer.h"
92 #include "extensions/browser/extension_registry.h"
93 #include "extensions/browser/extension_system.h"
94 #include "extensions/browser/uninstall_reason.h"
95 #include "extensions/common/constants.h"
96 #include "extensions/common/extension.h"
97 #include "extensions/common/extension_set.h"
98 #include "net/base/net_errors.h"
99 #include "net/dns/mock_host_resolver.h"
100 #include "net/test/spawned_test_server/spawned_test_server.h"
101 #include "ui/base/l10n/l10n_util.h"
102 #include "ui/base/page_transition_types.h"
104 #if defined(OS_MACOSX)
105 #include "base/mac/mac_util.h"
106 #include "base/mac/scoped_nsautorelease_pool.h"
107 #include "chrome/browser/ui/cocoa/run_loop_testing.h"
111 #include "base/i18n/rtl.h"
112 #include "chrome/browser/browser_process.h"
115 using app_modal::AppModalDialog
;
116 using app_modal::AppModalDialogQueue
;
117 using app_modal::JavaScriptAppModalDialog
;
118 using base::ASCIIToUTF16
;
119 using content::InterstitialPage
;
120 using content::HostZoomMap
;
121 using content::NavigationController
;
122 using content::NavigationEntry
;
123 using content::OpenURLParams
;
124 using content::Referrer
;
125 using content::WebContents
;
126 using content::WebContentsObserver
;
127 using extensions::Extension
;
131 enum CertificateStatus
{ VALID_CERTIFICATE
, INVALID_CERTIFICATE
};
133 const char* kBeforeUnloadHTML
=
134 "<html><head><title>beforeunload</title></head><body>"
135 "<script>window.onbeforeunload=function(e){return 'foo'}</script>"
138 const char* kOpenNewBeforeUnloadPage
=
139 "w=window.open(); w.onbeforeunload=function(e){return 'foo'};";
141 const base::FilePath::CharType
* kBeforeUnloadFile
=
142 FILE_PATH_LITERAL("beforeunload.html");
144 const base::FilePath::CharType
* kTitle1File
= FILE_PATH_LITERAL("title1.html");
145 const base::FilePath::CharType
* kTitle2File
= FILE_PATH_LITERAL("title2.html");
147 const base::FilePath::CharType kDocRoot
[] =
148 FILE_PATH_LITERAL("chrome/test/data");
150 // Given a page title, returns the expected window caption string.
151 base::string16
WindowCaptionFromPageTitle(const base::string16
& page_title
) {
152 #if defined(OS_MACOSX) || defined(OS_CHROMEOS)
153 // On Mac or ChromeOS, we don't want to suffix the page title with
154 // the application name.
155 if (page_title
.empty())
156 return l10n_util::GetStringUTF16(IDS_BROWSER_WINDOW_MAC_TAB_UNTITLED
);
159 if (page_title
.empty())
160 return l10n_util::GetStringUTF16(IDS_PRODUCT_NAME
);
162 return l10n_util::GetStringFUTF16(IDS_BROWSER_WINDOW_TITLE_FORMAT
,
167 // Returns the number of active RenderProcessHosts.
168 int CountRenderProcessHosts() {
170 for (content::RenderProcessHost::iterator
i(
171 content::RenderProcessHost::AllHostsIterator());
172 !i
.IsAtEnd(); i
.Advance())
177 class MockTabStripModelObserver
: public TabStripModelObserver
{
179 MockTabStripModelObserver() : closing_count_(0) {}
181 void TabClosingAt(TabStripModel
* tab_strip_model
,
182 WebContents
* contents
,
183 int index
) override
{
187 int closing_count() const { return closing_count_
; }
192 DISALLOW_COPY_AND_ASSIGN(MockTabStripModelObserver
);
195 // Causes the browser to swap processes on a redirect to an HTTPS URL.
196 class TransferHttpsRedirectsContentBrowserClient
197 : public chrome::ChromeContentBrowserClient
{
199 bool ShouldSwapProcessesForRedirect(
200 content::ResourceContext
* resource_context
,
201 const GURL
& current_url
,
202 const GURL
& new_url
) override
{
203 return new_url
.SchemeIs(url::kHttpsScheme
);
207 // Used by CloseWithAppMenuOpen. Invokes CloseWindow on the supplied browser.
208 void CloseWindowCallback(Browser
* browser
) {
209 chrome::CloseWindow(browser
);
212 // Used by CloseWithAppMenuOpen. Posts a CloseWindowCallback and shows the app
214 void RunCloseWithAppMenuCallback(Browser
* browser
) {
215 // ShowAppMenu is modal under views. Schedule a task that closes the window.
216 base::MessageLoop::current()->task_runner()->PostTask(
217 FROM_HERE
, base::Bind(&CloseWindowCallback
, browser
));
218 chrome::ShowAppMenu(browser
);
221 // Displays "INTERSTITIAL" while the interstitial is attached.
222 // (InterstitialPage can be used in a test directly, but there would be no way
223 // to visually tell if it is showing or not.)
224 class TestInterstitialPage
: public content::InterstitialPageDelegate
{
226 TestInterstitialPage(WebContents
* tab
, bool new_navigation
, const GURL
& url
) {
227 interstitial_page_
= InterstitialPage::Create(
228 tab
, new_navigation
, url
, this);
229 interstitial_page_
->Show();
231 ~TestInterstitialPage() override
{}
233 interstitial_page_
->Proceed();
236 interstitial_page_
->DontProceed();
239 std::string
GetHTMLContents() override
{ return "<h1>INTERSTITIAL</h1>"; }
242 InterstitialPage
* interstitial_page_
; // Owns us.
245 class RenderViewSizeObserver
: public content::WebContentsObserver
{
247 RenderViewSizeObserver(content::WebContents
* web_contents
,
248 BrowserWindow
* browser_window
)
249 : WebContentsObserver(web_contents
),
250 browser_window_(browser_window
) {
253 void GetSizeForRenderViewHost(
254 content::RenderViewHost
* render_view_host
,
255 gfx::Size
* rwhv_create_size
,
256 gfx::Size
* rwhv_commit_size
,
257 gfx::Size
* wcv_commit_size
) {
258 RenderViewSizes::const_iterator result
= render_view_sizes_
.end();
259 result
= render_view_sizes_
.find(render_view_host
);
260 if (result
!= render_view_sizes_
.end()) {
261 *rwhv_create_size
= result
->second
.rwhv_create_size
;
262 *rwhv_commit_size
= result
->second
.rwhv_commit_size
;
263 *wcv_commit_size
= result
->second
.wcv_commit_size
;
267 void set_wcv_resize_insets(const gfx::Size
& wcv_resize_insets
) {
268 wcv_resize_insets_
= wcv_resize_insets
;
271 // Cache the size when RenderViewHost is first created.
272 void RenderViewCreated(content::RenderViewHost
* render_view_host
) override
{
273 render_view_sizes_
[render_view_host
].rwhv_create_size
=
274 render_view_host
->GetView()->GetViewBounds().size();
277 // Enlarge WebContentsView by |wcv_resize_insets_| while the navigation entry
279 void DidStartNavigationToPendingEntry(
281 NavigationController::ReloadType reload_type
) override
{
282 if (wcv_resize_insets_
.IsEmpty())
284 // Resizing the main browser window by |wcv_resize_insets_| will
285 // automatically resize the WebContentsView by the same amount.
286 // Just resizing WebContentsView directly doesn't work on Linux, because the
287 // next automatic layout of the browser window will resize WebContentsView
288 // back to the previous size. To make it consistent, resize main browser
289 // window on all platforms.
290 gfx::Rect
bounds(browser_window_
->GetBounds());
291 gfx::Size
size(bounds
.size());
292 size
.Enlarge(wcv_resize_insets_
.width(), wcv_resize_insets_
.height());
293 bounds
.set_size(size
);
294 browser_window_
->SetBounds(bounds
);
295 // Let the message loop run so that resize actually takes effect.
296 content::RunAllPendingInMessageLoop();
299 // Cache the sizes of RenderWidgetHostView and WebContentsView when the
300 // navigation entry is committed, which is before
301 // WebContentsDelegate::DidNavigateMainFramePostCommit is called.
302 void NavigationEntryCommitted(
303 const content::LoadCommittedDetails
& details
) override
{
304 content::RenderViewHost
* rvh
= web_contents()->GetRenderViewHost();
305 render_view_sizes_
[rvh
].rwhv_commit_size
=
306 web_contents()->GetRenderWidgetHostView()->GetViewBounds().size();
307 render_view_sizes_
[rvh
].wcv_commit_size
=
308 web_contents()->GetContainerBounds().size();
313 gfx::Size rwhv_create_size
; // Size of RenderWidgetHostView when created.
314 gfx::Size rwhv_commit_size
; // Size of RenderWidgetHostView when committed.
315 gfx::Size wcv_commit_size
; // Size of WebContentsView when committed.
318 typedef std::map
<content::RenderViewHost
*, Sizes
> RenderViewSizes
;
319 RenderViewSizes render_view_sizes_
;
320 // Enlarge WebContentsView by this size insets in
321 // DidStartNavigationToPendingEntry.
322 gfx::Size wcv_resize_insets_
;
323 BrowserWindow
* browser_window_
; // Weak ptr.
325 DISALLOW_COPY_AND_ASSIGN(RenderViewSizeObserver
);
328 void ProceedThroughInterstitial(content::WebContents
* web_contents
) {
329 InterstitialPage
* interstitial_page
= web_contents
->GetInterstitialPage();
330 ASSERT_TRUE(interstitial_page
);
332 content::WindowedNotificationObserver
observer(
333 content::NOTIFICATION_LOAD_STOP
,
334 content::Source
<NavigationController
>(&web_contents
->GetController()));
335 interstitial_page
->Proceed();
339 bool GetFilePathWithHostAndPortReplacement(
340 const std::string
& original_file_path
,
341 const net::HostPortPair
& host_port_pair
,
342 std::string
* replacement_path
) {
343 std::vector
<net::SpawnedTestServer::StringPair
> replacement_text
;
344 replacement_text
.push_back(
345 make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair
.ToString()));
346 return net::SpawnedTestServer::GetFilePathWithReplacements(
347 original_file_path
, replacement_text
, replacement_path
);
350 // A WebContentsObserver useful for testing the SecurityStyleChanged()
351 // method: it keeps track of the latest security style and explanation
353 class SecurityStyleTestObserver
: public WebContentsObserver
{
355 explicit SecurityStyleTestObserver(content::WebContents
* web_contents
)
356 : content::WebContentsObserver(web_contents
),
357 latest_security_style_(content::SECURITY_STYLE_UNKNOWN
) {}
358 ~SecurityStyleTestObserver() override
{}
360 void SecurityStyleChanged(content::SecurityStyle security_style
,
361 const content::SecurityStyleExplanations
&
362 security_style_explanations
) override
{
363 latest_security_style_
= security_style
;
364 latest_explanations_
= security_style_explanations
;
367 content::SecurityStyle
latest_security_style() const {
368 return latest_security_style_
;
371 const content::SecurityStyleExplanations
& latest_explanations() const {
372 return latest_explanations_
;
375 void ClearLatestSecurityStyleAndExplanations() {
376 latest_security_style_
= content::SECURITY_STYLE_UNKNOWN
;
377 latest_explanations_
= content::SecurityStyleExplanations();
381 content::SecurityStyle latest_security_style_
;
382 content::SecurityStyleExplanations latest_explanations_
;
384 DISALLOW_COPY_AND_ASSIGN(SecurityStyleTestObserver
);
387 // Check that |observer|'s latest event was for an expired certificate
388 // and that it saw the proper SecurityStyle and explanations.
389 void CheckBrokenSecurityStyle(const SecurityStyleTestObserver
& observer
,
391 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN
,
392 observer
.latest_security_style());
394 const content::SecurityStyleExplanations
& expired_explanation
=
395 observer
.latest_explanations();
396 EXPECT_EQ(0u, expired_explanation
.warning_explanations
.size());
397 ASSERT_EQ(1u, expired_explanation
.broken_explanations
.size());
399 // Check that the summary and description are as expected.
400 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_CERTIFICATE_CHAIN_ERROR
),
401 expired_explanation
.broken_explanations
[0].summary
);
403 base::string16 error_string
= base::UTF8ToUTF16(net::ErrorToString(error
));
404 EXPECT_EQ(l10n_util::GetStringFUTF8(
405 IDS_CERTIFICATE_CHAIN_ERROR_DESCRIPTION_FORMAT
, error_string
),
406 expired_explanation
.broken_explanations
[0].description
);
409 // Checks that the given |secure_explanations| contains appropriate
410 // an appropriate explanation if the certificate status is valid.
411 void CheckSecureExplanations(
412 const std::vector
<content::SecurityStyleExplanation
>& secure_explanations
,
413 CertificateStatus cert_status
) {
414 if (cert_status
!= VALID_CERTIFICATE
) {
415 EXPECT_EQ(0u, secure_explanations
.size());
419 EXPECT_EQ(1u, secure_explanations
.size());
420 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE
),
421 secure_explanations
[0].summary
);
422 EXPECT_EQ(l10n_util::GetStringUTF8(IDS_VALID_SERVER_CERTIFICATE_DESCRIPTION
),
423 secure_explanations
[0].description
);
428 class BrowserTest
: public ExtensionBrowserTest
{
430 // In RTL locales wrap the page title with RTL embedding characters so that it
431 // matches the value returned by GetWindowTitle().
432 base::string16
LocaleWindowCaptionFromPageTitle(
433 const base::string16
& expected_title
) {
434 base::string16 page_title
= WindowCaptionFromPageTitle(expected_title
);
436 std::string locale
= g_browser_process
->GetApplicationLocale();
437 if (base::i18n::GetTextDirectionForLocale(locale
.c_str()) ==
438 base::i18n::RIGHT_TO_LEFT
) {
439 base::i18n::WrapStringWithLTRFormatting(&page_title
);
444 // Do we need to use the above code on POSIX as well?
449 // Returns the app extension aptly named "App Test".
450 const Extension
* GetExtension() {
451 extensions::ExtensionRegistry
* registry
=
452 extensions::ExtensionRegistry::Get(browser()->profile());
453 for (const scoped_refptr
<const extensions::Extension
>& extension
:
454 registry
->enabled_extensions()) {
455 if (extension
->name() == "App Test")
456 return extension
.get();
463 // Launch the app on a page with no title, check that the app title was set
465 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoTitle
) {
466 #if defined(OS_WIN) && defined(USE_ASH)
467 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
468 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
469 switches::kAshBrowserTests
))
473 ui_test_utils::NavigateToURL(
474 browser(), ui_test_utils::GetTestUrl(
475 base::FilePath(base::FilePath::kCurrentDirectory
),
476 base::FilePath(kTitle1File
)));
477 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(ASCIIToUTF16("title1.html")),
478 browser()->GetWindowTitleForCurrentTab());
479 base::string16 tab_title
;
480 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title
));
481 EXPECT_EQ(ASCIIToUTF16("title1.html"), tab_title
);
484 // Check that a file:// URL displays the filename, but no path, with any ref or
485 // query parameters following it if the content does not have a <title> tag.
486 // Specifically verify the cases where the ref or query parameters have a '/'
487 // character in them. This is a regression test for
488 // https://crbug.com/503003.
489 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoTitleFileUrl
) {
490 #if defined(OS_WIN) && defined(USE_ASH)
491 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
492 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
493 switches::kAshBrowserTests
))
497 // Note that the host names used and the order of these cases are by design.
498 // There must be unique query parameters and references per case (i.e. the
499 // indexed foo*.com hosts) because if the same query parameter is repeated in
500 // a row, then the navigation may not actually happen, as it will only appear
501 // as a reference change. Additionally, cases with references first must
502 // appear after a query parameter case since otherwise it will not be a
508 {"#https://foo1.com", "file:/// URL with slash in ref"},
509 {"?x=https://foo2.com", "file:/// URL with slash in query parameter"},
510 {"?x=https://foo3.com#https://foo3.com",
511 "file:/// URL with slashes in query parameter and ref"},
512 {"#https://foo4.com?x=https://foo4.com",
513 "file:/// URL with slashes in ref and query parameter"},
514 {"?x=https://foo6.com?x=https://foo6.com",
515 "file:/// URL with slashes in multiple query parameter"},
516 {"#https://foo5.com#https://foo5.com",
517 "file:/// URL with slashes in multiple refs"}};
519 GURL prefix_url
= ui_test_utils::GetTestUrl(
520 base::FilePath(base::FilePath::kCurrentDirectory
),
521 base::FilePath(kTitle1File
));
522 base::string16 tab_title
;
523 base::string16 test_title
;
524 for (const auto& c
: cases
) {
525 SCOPED_TRACE(c
.message
);
526 GURL
url(prefix_url
.spec() + c
.suffix
);
527 test_title
= ASCIIToUTF16("title1.html" + c
.suffix
);
528 content::TitleWatcher
title_watcher(
529 browser()->tab_strip_model()->GetActiveWebContents(), test_title
);
530 ui_test_utils::NavigateToURL(browser(), url
);
531 EXPECT_EQ(test_title
, title_watcher
.WaitAndGetTitle());
535 // Launch the app, navigate to a page with a title, check that the app title
536 // was set correctly.
537 IN_PROC_BROWSER_TEST_F(BrowserTest
, Title
) {
538 #if defined(OS_WIN) && defined(USE_ASH)
539 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
540 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
541 switches::kAshBrowserTests
))
545 ui_test_utils::NavigateToURL(
546 browser(), ui_test_utils::GetTestUrl(
547 base::FilePath(base::FilePath::kCurrentDirectory
),
548 base::FilePath(kTitle2File
)));
549 const base::string16
test_title(ASCIIToUTF16("Title Of Awesomeness"));
550 EXPECT_EQ(LocaleWindowCaptionFromPageTitle(test_title
),
551 browser()->GetWindowTitleForCurrentTab());
552 base::string16 tab_title
;
553 ASSERT_TRUE(ui_test_utils::GetCurrentTabTitle(browser(), &tab_title
));
554 EXPECT_EQ(test_title
, tab_title
);
557 IN_PROC_BROWSER_TEST_F(BrowserTest
, JavascriptAlertActivatesTab
) {
558 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
559 base::FilePath::kCurrentDirectory
), base::FilePath(kTitle1File
)));
560 ui_test_utils::NavigateToURL(browser(), url
);
561 AddTabAtIndex(0, url
, ui::PAGE_TRANSITION_TYPED
);
562 EXPECT_EQ(2, browser()->tab_strip_model()->count());
563 EXPECT_EQ(0, browser()->tab_strip_model()->active_index());
564 WebContents
* second_tab
= browser()->tab_strip_model()->GetWebContentsAt(1);
565 ASSERT_TRUE(second_tab
);
566 second_tab
->GetMainFrame()->ExecuteJavaScriptForTests(
567 ASCIIToUTF16("alert('Activate!');"));
568 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
569 alert
->CloseModalDialog();
570 EXPECT_EQ(2, browser()->tab_strip_model()->count());
571 EXPECT_EQ(1, browser()->tab_strip_model()->active_index());
575 #if defined(OS_WIN) && !defined(NDEBUG)
576 // http://crbug.com/114859. Times out frequently on Windows.
577 #define MAYBE_ThirtyFourTabs DISABLED_ThirtyFourTabs
579 #define MAYBE_ThirtyFourTabs ThirtyFourTabs
582 // Create 34 tabs and verify that a lot of processes have been created. The
583 // exact number of processes depends on the amount of memory. Previously we
584 // had a hard limit of 31 processes and this test is mainly directed at
585 // verifying that we don't crash when we pass this limit.
586 // Warning: this test can take >30 seconds when running on a slow (low
587 // memory?) Mac builder.
588 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_ThirtyFourTabs
) {
589 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
590 base::FilePath::kCurrentDirectory
), base::FilePath(kTitle2File
)));
592 // There is one initial tab.
593 const int kTabCount
= 34;
594 for (int ix
= 0; ix
!= (kTabCount
- 1); ++ix
) {
595 chrome::AddSelectedTabWithURL(browser(), url
,
596 ui::PAGE_TRANSITION_TYPED
);
598 EXPECT_EQ(kTabCount
, browser()->tab_strip_model()->count());
600 // See GetMaxRendererProcessCount() in
601 // content/browser/renderer_host/render_process_host_impl.cc
602 // for the algorithm to decide how many processes to create.
603 const int kExpectedProcessCount
=
604 #if defined(ARCH_CPU_64_BITS)
609 if (base::SysInfo::AmountOfPhysicalMemoryMB() >= 2048) {
610 EXPECT_GE(CountRenderProcessHosts(), kExpectedProcessCount
);
612 EXPECT_LT(CountRenderProcessHosts(), kExpectedProcessCount
);
616 // Test that a browser-initiated navigation to an aborted URL load leaves around
617 // a pending entry if we start from the NTP but not from a normal page.
618 // See http://crbug.com/355537.
619 IN_PROC_BROWSER_TEST_F(BrowserTest
, ClearPendingOnFailUnlessNTP
) {
620 ASSERT_TRUE(test_server()->Start());
621 WebContents
* web_contents
=
622 browser()->tab_strip_model()->GetActiveWebContents();
623 GURL
ntp_url(search::GetNewTabPageURL(browser()->profile()));
624 ui_test_utils::NavigateToURL(browser(), ntp_url
);
626 // Navigate to a 204 URL (aborts with no content) on the NTP and make sure it
627 // sticks around so that the user can edit it.
628 GURL
abort_url(test_server()->GetURL("nocontent"));
630 content::WindowedNotificationObserver
stop_observer(
631 content::NOTIFICATION_LOAD_STOP
,
632 content::Source
<NavigationController
>(
633 &web_contents
->GetController()));
634 browser()->OpenURL(OpenURLParams(abort_url
, Referrer(), CURRENT_TAB
,
635 ui::PAGE_TRANSITION_TYPED
, false));
636 stop_observer
.Wait();
637 EXPECT_TRUE(web_contents
->GetController().GetPendingEntry());
638 EXPECT_EQ(abort_url
, web_contents
->GetVisibleURL());
641 // Navigate to a real URL.
642 GURL
real_url(test_server()->GetURL("title1.html"));
643 ui_test_utils::NavigateToURL(browser(), real_url
);
644 EXPECT_EQ(real_url
, web_contents
->GetVisibleURL());
646 // Now navigating to a 204 URL should clear the pending entry.
648 content::WindowedNotificationObserver
stop_observer(
649 content::NOTIFICATION_LOAD_STOP
,
650 content::Source
<NavigationController
>(
651 &web_contents
->GetController()));
652 browser()->OpenURL(OpenURLParams(abort_url
, Referrer(), CURRENT_TAB
,
653 ui::PAGE_TRANSITION_TYPED
, false));
654 stop_observer
.Wait();
655 EXPECT_FALSE(web_contents
->GetController().GetPendingEntry());
656 EXPECT_EQ(real_url
, web_contents
->GetVisibleURL());
660 // Test for crbug.com/297289. Ensure that modal dialogs are closed when a
661 // cross-process navigation is ready to commit.
662 // Flaky test, see https://crbug.com/445155.
663 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_CrossProcessNavCancelsDialogs
) {
664 ASSERT_TRUE(test_server()->Start());
665 host_resolver()->AddRule("www.example.com", "127.0.0.1");
666 GURL
url(test_server()->GetURL("empty.html"));
667 ui_test_utils::NavigateToURL(browser(), url
);
669 // Test this with multiple alert dialogs to ensure that we can navigate away
670 // even if the renderer tries to synchronously create more.
671 // See http://crbug.com/312490.
672 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
673 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
674 ASCIIToUTF16("alert('one'); alert('two');"));
675 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
676 EXPECT_TRUE(alert
->IsValid());
677 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
678 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
680 // A cross-site navigation should force the dialog to close.
681 GURL
url2("http://www.example.com/empty.html");
682 ui_test_utils::NavigateToURL(browser(), url2
);
683 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
685 // Make sure input events still work in the renderer process.
686 EXPECT_FALSE(contents
->GetRenderProcessHost()->IgnoreInputEvents());
689 // Make sure that dialogs are closed after a renderer process dies, and that
690 // subsequent navigations work. See http://crbug/com/343265.
691 IN_PROC_BROWSER_TEST_F(BrowserTest
, SadTabCancelsDialogs
) {
692 ASSERT_TRUE(test_server()->Start());
693 host_resolver()->AddRule("www.example.com", "127.0.0.1");
694 GURL
beforeunload_url(test_server()->GetURL("files/beforeunload.html"));
695 ui_test_utils::NavigateToURL(browser(), beforeunload_url
);
697 // Start a navigation to trigger the beforeunload dialog.
698 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
699 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
700 ASCIIToUTF16("window.location.href = 'data:text/html,foo'"));
701 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
702 EXPECT_TRUE(alert
->IsValid());
703 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
704 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
706 // Crash the renderer process and ensure the dialog is gone.
707 content::RenderProcessHost
* child_process
= contents
->GetRenderProcessHost();
708 content::RenderProcessHostWatcher
crash_observer(
710 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
711 child_process
->Shutdown(0, false);
712 crash_observer
.Wait();
713 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
715 // Make sure subsequent navigations work.
716 GURL
url2("http://www.example.com/files/empty.html");
717 ui_test_utils::NavigateToURL(browser(), url2
);
720 // Make sure that dialogs opened by subframes are closed when the process dies.
721 // See http://crbug.com/366510.
722 IN_PROC_BROWSER_TEST_F(BrowserTest
, SadTabCancelsSubframeDialogs
) {
723 // Navigate to an iframe that opens an alert dialog.
724 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
725 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
726 ASCIIToUTF16("window.location.href = 'data:text/html,"
727 "<iframe srcdoc=\"<script>alert(1)</script>\">'"));
728 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
729 EXPECT_TRUE(alert
->IsValid());
730 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
731 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
733 // Crash the renderer process and ensure the dialog is gone.
734 content::RenderProcessHost
* child_process
= contents
->GetRenderProcessHost();
735 content::RenderProcessHostWatcher
crash_observer(
737 content::RenderProcessHostWatcher::WATCH_FOR_PROCESS_EXIT
);
738 child_process
->Shutdown(0, false);
739 crash_observer
.Wait();
740 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
742 // Make sure subsequent navigations work.
743 GURL
url2("data:text/html,foo");
744 ui_test_utils::NavigateToURL(browser(), url2
);
747 // Make sure modal dialogs within a guestview are closed when an interstitial
748 // page is showing. See crbug.com/482380.
749 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCancelsGuestViewDialogs
) {
750 // Navigate to a PDF, which is loaded within a guestview.
751 ASSERT_TRUE(test_server()->Start());
752 GURL
pdf_with_dialog(test_server()->GetURL("files/alert_dialog.pdf"));
753 ui_test_utils::NavigateToURL(browser(), pdf_with_dialog
);
755 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
756 EXPECT_TRUE(alert
->IsValid());
757 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
758 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
760 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
762 TestInterstitialPage
* interstitial
=
763 new TestInterstitialPage(contents
, false, GURL());
764 content::WaitForInterstitialAttach(contents
);
766 // The interstitial should have closed the dialog.
767 EXPECT_TRUE(contents
->ShowingInterstitialPage());
768 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
770 interstitial
->DontProceed();
773 // Test for crbug.com/22004. Reloading a page with a before unload handler and
774 // then canceling the dialog should not leave the throbber spinning.
775 IN_PROC_BROWSER_TEST_F(BrowserTest
, ReloadThenCancelBeforeUnload
) {
776 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
777 ui_test_utils::NavigateToURL(browser(), url
);
779 // Navigate to another page, but click cancel in the dialog. Make sure that
780 // the throbber stops spinning.
781 chrome::Reload(browser(), CURRENT_TAB
);
782 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
783 alert
->CloseModalDialog();
785 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading());
787 // Clear the beforeunload handler so the test can easily exit.
788 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
789 ExecuteJavaScriptForTests(ASCIIToUTF16("onbeforeunload=null;"));
792 class RedirectObserver
: public content::WebContentsObserver
{
794 explicit RedirectObserver(content::WebContents
* web_contents
)
795 : WebContentsObserver(web_contents
) {
798 void DidNavigateAnyFrame(
799 content::RenderFrameHost
* render_frame_host
,
800 const content::LoadCommittedDetails
& details
,
801 const content::FrameNavigateParams
& params
) override
{
805 void WebContentsDestroyed() override
{
806 // Make sure we don't close the tab while the observer is in scope.
807 // See http://crbug.com/314036.
808 FAIL() << "WebContents closed during navigation (http://crbug.com/314036).";
811 const content::FrameNavigateParams
& params() const {
816 content::FrameNavigateParams params_
;
818 DISALLOW_COPY_AND_ASSIGN(RedirectObserver
);
821 // Ensure that a transferred cross-process navigation does not generate
822 // DidStopLoading events until the navigation commits. If it did, then
823 // ui_test_utils::NavigateToURL would proceed before the URL had committed.
824 // http://crbug.com/243957.
825 IN_PROC_BROWSER_TEST_F(BrowserTest
, NoStopDuringTransferUntilCommit
) {
826 // Create HTTP and HTTPS servers for a cross-site transition.
827 ASSERT_TRUE(test_server()->Start());
828 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
829 net::SpawnedTestServer::kLocalhost
,
830 base::FilePath(kDocRoot
));
831 ASSERT_TRUE(https_test_server
.Start());
833 // Temporarily replace ContentBrowserClient with one that will cause a
834 // process swap on all redirects to HTTPS URLs.
835 TransferHttpsRedirectsContentBrowserClient new_client
;
836 content::ContentBrowserClient
* old_client
=
837 SetBrowserClientForTesting(&new_client
);
839 GURL
init_url(test_server()->GetURL("files/title1.html"));
840 ui_test_utils::NavigateToURL(browser(), init_url
);
842 // Navigate to a same-site page that redirects, causing a transfer.
843 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
845 // Create a RedirectObserver that goes away before we close the tab.
847 RedirectObserver
redirect_observer(contents
);
848 GURL
dest_url(https_test_server
.GetURL("files/title2.html"));
849 GURL
redirect_url(test_server()->GetURL("server-redirect?" +
851 ui_test_utils::NavigateToURL(browser(), redirect_url
);
853 // We should immediately see the new committed entry.
854 EXPECT_FALSE(contents
->GetController().GetPendingEntry());
856 contents
->GetController().GetLastCommittedEntry()->GetURL());
858 // We should keep track of the original request URL, redirect chain, and
859 // page transition type during a transfer, since these are necessary for
860 // history autocomplete to work.
861 EXPECT_EQ(redirect_url
, contents
->GetController().GetLastCommittedEntry()->
862 GetOriginalRequestURL());
863 EXPECT_EQ(2U, redirect_observer
.params().redirects
.size());
864 EXPECT_EQ(redirect_url
, redirect_observer
.params().redirects
.at(0));
865 EXPECT_EQ(dest_url
, redirect_observer
.params().redirects
.at(1));
866 EXPECT_TRUE(ui::PageTransitionCoreTypeIs(
867 redirect_observer
.params().transition
, ui::PAGE_TRANSITION_TYPED
));
870 // Restore previous browser client.
871 SetBrowserClientForTesting(old_client
);
874 // Tests that a cross-process redirect will only cause the beforeunload
875 // handler to run once.
876 IN_PROC_BROWSER_TEST_F(BrowserTest
, SingleBeforeUnloadAfterRedirect
) {
877 // Create HTTP and HTTPS servers for a cross-site transition.
878 ASSERT_TRUE(test_server()->Start());
879 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
880 net::SpawnedTestServer::kLocalhost
,
881 base::FilePath(kDocRoot
));
882 ASSERT_TRUE(https_test_server
.Start());
884 // Temporarily replace ContentBrowserClient with one that will cause a
885 // process swap on all redirects to HTTPS URLs.
886 TransferHttpsRedirectsContentBrowserClient new_client
;
887 content::ContentBrowserClient
* old_client
=
888 SetBrowserClientForTesting(&new_client
);
890 // Navigate to a page with a beforeunload handler.
891 GURL
url(test_server()->GetURL("files/beforeunload.html"));
892 ui_test_utils::NavigateToURL(browser(), url
);
894 // Navigate to a URL that redirects to another process and approve the
895 // beforeunload dialog that pops up.
896 content::WindowedNotificationObserver
nav_observer(
897 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
898 content::NotificationService::AllSources());
899 GURL
https_url(https_test_server
.GetURL("files/title1.html"));
900 GURL
redirect_url(test_server()->GetURL("server-redirect?" +
902 browser()->OpenURL(OpenURLParams(redirect_url
, Referrer(), CURRENT_TAB
,
903 ui::PAGE_TRANSITION_TYPED
, false));
904 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
906 static_cast<JavaScriptAppModalDialog
*>(alert
)->is_before_unload_dialog());
907 alert
->native_dialog()->AcceptAppModalDialog();
910 // Restore previous browser client.
911 SetBrowserClientForTesting(old_client
);
914 // Test for crbug.com/80401. Canceling a before unload dialog should reset
915 // the URL to the previous page's URL.
916 IN_PROC_BROWSER_TEST_F(BrowserTest
, CancelBeforeUnloadResetsURL
) {
917 GURL
url(ui_test_utils::GetTestUrl(base::FilePath(
918 base::FilePath::kCurrentDirectory
), base::FilePath(kBeforeUnloadFile
)));
919 ui_test_utils::NavigateToURL(browser(), url
);
921 // Navigate to a page that triggers a cross-site transition.
922 ASSERT_TRUE(test_server()->Start());
923 GURL
url2(test_server()->GetURL("files/title1.html"));
924 browser()->OpenURL(OpenURLParams(
925 url2
, Referrer(), CURRENT_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
927 content::WindowedNotificationObserver
host_destroyed_observer(
928 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
,
929 content::NotificationService::AllSources());
931 // Cancel the dialog.
932 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
933 alert
->CloseModalDialog();
935 browser()->tab_strip_model()->GetActiveWebContents()->IsLoading());
937 // Verify there are no pending history items after the dialog is cancelled.
938 // (see crbug.com/93858)
939 NavigationEntry
* entry
= browser()->tab_strip_model()->
940 GetActiveWebContents()->GetController().GetPendingEntry();
941 EXPECT_EQ(NULL
, entry
);
943 // Wait for the ShouldClose_ACK to arrive. We can detect it by waiting for
944 // the pending RVH to be destroyed.
945 host_destroyed_observer
.Wait();
946 EXPECT_EQ(url
, browser()->toolbar_model()->GetURL());
948 // Clear the beforeunload handler so the test can easily exit.
949 browser()->tab_strip_model()->GetActiveWebContents()->GetMainFrame()->
950 ExecuteJavaScriptForTests(ASCIIToUTF16("onbeforeunload=null;"));
953 // Test for crbug.com/11647. A page closed with window.close() should not have
954 // two beforeunload dialogs shown.
955 // http://crbug.com/410891
956 IN_PROC_BROWSER_TEST_F(BrowserTest
,
957 DISABLED_SingleBeforeUnloadAfterWindowClose
) {
960 ->GetActiveWebContents()
962 ->ExecuteJavaScriptWithUserGestureForTests(
963 ASCIIToUTF16(kOpenNewBeforeUnloadPage
));
965 // Close the new window with JavaScript, which should show a single
966 // beforeunload dialog. Then show another alert, to make it easy to verify
967 // that a second beforeunload dialog isn't shown.
970 ->GetWebContentsAt(0)
972 ->ExecuteJavaScriptWithUserGestureForTests(
973 ASCIIToUTF16("w.close(); alert('bar');"));
974 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
975 alert
->native_dialog()->AcceptAppModalDialog();
977 alert
= ui_test_utils::WaitForAppModalDialog();
978 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog
*>(alert
)->
979 is_before_unload_dialog());
980 alert
->native_dialog()->AcceptAppModalDialog();
983 // BrowserTest.BeforeUnloadVsBeforeReload times out on Windows.
984 // http://crbug.com/130411
986 #define MAYBE_BeforeUnloadVsBeforeReload DISABLED_BeforeUnloadVsBeforeReload
988 #define MAYBE_BeforeUnloadVsBeforeReload BeforeUnloadVsBeforeReload
991 // Test that when a page has an onunload handler, reloading a page shows a
992 // different dialog than navigating to a different page.
993 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_BeforeUnloadVsBeforeReload
) {
994 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
995 ui_test_utils::NavigateToURL(browser(), url
);
997 // Reload the page, and check that we get a "before reload" dialog.
998 chrome::Reload(browser(), CURRENT_TAB
);
999 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
1000 EXPECT_TRUE(static_cast<JavaScriptAppModalDialog
*>(alert
)->is_reload());
1002 // Cancel the reload.
1003 alert
->native_dialog()->CancelAppModalDialog();
1005 // Navigate to another url, and check that we get a "before unload" dialog.
1006 GURL
url2(url::kAboutBlankURL
);
1007 browser()->OpenURL(OpenURLParams(
1008 url2
, Referrer(), CURRENT_TAB
, ui::PAGE_TRANSITION_TYPED
, false));
1010 alert
= ui_test_utils::WaitForAppModalDialog();
1011 EXPECT_FALSE(static_cast<JavaScriptAppModalDialog
*>(alert
)->is_reload());
1013 // Accept the navigation so we end up on a page without a beforeunload hook.
1014 alert
->native_dialog()->AcceptAppModalDialog();
1017 // BeforeUnloadAtQuitWithTwoWindows is a regression test for
1018 // http://crbug.com/11842. It opens two windows, one of which has a
1019 // beforeunload handler and attempts to exit cleanly.
1020 class BeforeUnloadAtQuitWithTwoWindows
: public InProcessBrowserTest
{
1022 // This test is for testing a specific shutdown behavior. This mimics what
1023 // happens in InProcessBrowserTest::RunTestOnMainThread and QuitBrowsers, but
1024 // ensures that it happens through the single IDC_EXIT of the test.
1025 void TearDownOnMainThread() override
{
1026 // Cycle both the MessageLoop and the Cocoa runloop twice to flush out any
1027 // Chrome work that generates Cocoa work. Do this twice since there are two
1028 // Browsers that must be closed.
1032 // Run the application event loop to completion, which will cycle the
1033 // native MessagePump on all platforms.
1034 base::MessageLoop::current()->task_runner()->PostTask(
1035 FROM_HERE
, base::MessageLoop::QuitClosure());
1036 base::MessageLoop::current()->Run();
1038 // Take care of any remaining Cocoa work.
1041 // At this point, quit should be for real now.
1042 ASSERT_EQ(0u, chrome::GetTotalBrowserCount());
1045 // A helper function that cycles the MessageLoop, and on Mac, the Cocoa run
1046 // loop. It also drains the NSAutoreleasePool.
1047 void CycleRunLoops() {
1048 content::RunAllPendingInMessageLoop();
1049 #if defined(OS_MACOSX)
1050 chrome::testing::NSRunLoopRunAllPending();
1051 AutoreleasePool()->Recycle();
1056 // Disabled, http://crbug.com/159214 .
1057 IN_PROC_BROWSER_TEST_F(BeforeUnloadAtQuitWithTwoWindows
,
1058 DISABLED_IfThisTestTimesOutItIndicatesFAILURE
) {
1059 // In the first browser, set up a page that has a beforeunload handler.
1060 GURL
url(std::string("data:text/html,") + kBeforeUnloadHTML
);
1061 ui_test_utils::NavigateToURL(browser(), url
);
1063 // Open a second browser window at about:blank.
1064 ui_test_utils::BrowserAddedObserver browser_added_observer
;
1065 chrome::NewEmptyWindow(browser()->profile(), chrome::GetActiveDesktop());
1066 Browser
* second_window
= browser_added_observer
.WaitForSingleNewBrowser();
1067 ui_test_utils::NavigateToURL(second_window
, GURL(url::kAboutBlankURL
));
1069 // Tell the application to quit. IDC_EXIT calls AttemptUserExit, which on
1070 // everything but ChromeOS allows unload handlers to block exit. On that
1071 // platform, though, it exits unconditionally. See the comment and bug ID
1072 // in AttemptUserExit() in application_lifetime.cc.
1073 #if defined(OS_CHROMEOS)
1074 chrome::AttemptExit();
1076 chrome::ExecuteCommand(second_window
, IDC_EXIT
);
1079 // The beforeunload handler will run at exit, ensure it does, and then accept
1080 // it to allow shutdown to proceed.
1081 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
1084 static_cast<JavaScriptAppModalDialog
*>(alert
)->is_before_unload_dialog());
1085 alert
->native_dialog()->AcceptAppModalDialog();
1087 // But wait there's more! If this test times out, it likely means that the
1088 // browser has not been able to quit correctly, indicating there's a
1089 // regression of the bug noted above.
1092 // Test that scripts can fork a new renderer process for a cross-site popup,
1093 // based on http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab.
1094 // The script must open a new tab, set its window.opener to null, and navigate
1095 // it to a cross-site URL. It should also work for meta-refreshes.
1096 // See http://crbug.com/93517.
1097 IN_PROC_BROWSER_TEST_F(BrowserTest
, NullOpenerRedirectForksProcess
) {
1098 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1099 switches::kDisablePopupBlocking
);
1101 // Create http and https servers for a cross-site transition.
1102 ASSERT_TRUE(test_server()->Start());
1103 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1104 net::SpawnedTestServer::kLocalhost
,
1105 base::FilePath(kDocRoot
));
1106 ASSERT_TRUE(https_test_server
.Start());
1107 GURL
http_url(test_server()->GetURL("files/title1.html"));
1108 GURL
https_url(https_test_server
.GetURL(std::string()));
1110 // Start with an http URL.
1111 ui_test_utils::NavigateToURL(browser(), http_url
);
1112 WebContents
* oldtab
= browser()->tab_strip_model()->GetActiveWebContents();
1113 content::RenderProcessHost
* process
= oldtab
->GetRenderProcessHost();
1115 // Now open a tab to a blank page, set its opener to null, and redirect it
1117 std::string redirect_popup
= "w=window.open();";
1118 redirect_popup
+= "w.opener=null;";
1119 redirect_popup
+= "w.document.location=\"";
1120 redirect_popup
+= https_url
.spec();
1121 redirect_popup
+= "\";";
1123 content::WindowedNotificationObserver
popup_observer(
1124 chrome::NOTIFICATION_TAB_ADDED
,
1125 content::NotificationService::AllSources());
1126 content::WindowedNotificationObserver
nav_observer(
1127 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1128 content::NotificationService::AllSources());
1129 oldtab
->GetMainFrame()->
1130 ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(redirect_popup
));
1132 // Wait for popup window to appear and finish navigating.
1133 popup_observer
.Wait();
1134 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1135 WebContents
* newtab
= browser()->tab_strip_model()->GetActiveWebContents();
1136 EXPECT_TRUE(newtab
);
1137 EXPECT_NE(oldtab
, newtab
);
1138 nav_observer
.Wait();
1139 ASSERT_TRUE(newtab
->GetController().GetLastCommittedEntry());
1140 EXPECT_EQ(https_url
.spec(),
1141 newtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1143 // Popup window should not be in the opener's process.
1144 content::RenderProcessHost
* popup_process
=
1145 newtab
->GetRenderProcessHost();
1146 EXPECT_NE(process
, popup_process
);
1148 // Now open a tab to a blank page, set its opener to null, and use a
1149 // meta-refresh to navigate it instead.
1150 std::string refresh_popup
= "w=window.open();";
1151 refresh_popup
+= "w.opener=null;";
1152 refresh_popup
+= "w.document.write(";
1153 refresh_popup
+= "'<META HTTP-EQUIV=\"refresh\" content=\"0; url=";
1154 refresh_popup
+= https_url
.spec();
1155 refresh_popup
+= "\">');w.document.close();";
1157 content::WindowedNotificationObserver
popup_observer2(
1158 chrome::NOTIFICATION_TAB_ADDED
,
1159 content::NotificationService::AllSources());
1160 content::WindowedNotificationObserver
nav_observer2(
1161 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1162 content::NotificationService::AllSources());
1163 oldtab
->GetMainFrame()->
1164 ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(refresh_popup
));
1166 // Wait for popup window to appear and finish navigating.
1167 popup_observer2
.Wait();
1168 ASSERT_EQ(3, browser()->tab_strip_model()->count());
1169 WebContents
* newtab2
= browser()->tab_strip_model()->GetActiveWebContents();
1170 EXPECT_TRUE(newtab2
);
1171 EXPECT_NE(oldtab
, newtab2
);
1172 nav_observer2
.Wait();
1173 ASSERT_TRUE(newtab2
->GetController().GetLastCommittedEntry());
1174 EXPECT_EQ(https_url
.spec(),
1175 newtab2
->GetController().GetLastCommittedEntry()->GetURL().spec());
1177 // This popup window should also not be in the opener's process.
1178 content::RenderProcessHost
* popup_process2
=
1179 newtab2
->GetRenderProcessHost();
1180 EXPECT_NE(process
, popup_process2
);
1183 // Tests that other popup navigations that do not follow the steps at
1184 // http://www.google.com/chrome/intl/en/webmasters-faq.html#newtab will not
1185 // fork a new renderer process.
1186 IN_PROC_BROWSER_TEST_F(BrowserTest
, OtherRedirectsDontForkProcess
) {
1187 base::CommandLine::ForCurrentProcess()->AppendSwitch(
1188 switches::kDisablePopupBlocking
);
1190 // Create http and https servers for a cross-site transition.
1191 ASSERT_TRUE(test_server()->Start());
1192 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1193 net::SpawnedTestServer::kLocalhost
,
1194 base::FilePath(kDocRoot
));
1195 ASSERT_TRUE(https_test_server
.Start());
1196 GURL
http_url(test_server()->GetURL("files/title1.html"));
1197 GURL
https_url(https_test_server
.GetURL(std::string()));
1199 // Start with an http URL.
1200 ui_test_utils::NavigateToURL(browser(), http_url
);
1201 WebContents
* oldtab
= browser()->tab_strip_model()->GetActiveWebContents();
1202 content::RenderProcessHost
* process
= oldtab
->GetRenderProcessHost();
1204 // Now open a tab to a blank page, set its opener to null, and redirect it
1206 std::string dont_fork_popup
= "w=window.open();";
1207 dont_fork_popup
+= "w.document.location=\"";
1208 dont_fork_popup
+= https_url
.spec();
1209 dont_fork_popup
+= "\";";
1211 content::WindowedNotificationObserver
popup_observer(
1212 chrome::NOTIFICATION_TAB_ADDED
,
1213 content::NotificationService::AllSources());
1214 content::WindowedNotificationObserver
nav_observer(
1215 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1216 content::NotificationService::AllSources());
1217 oldtab
->GetMainFrame()->
1218 ExecuteJavaScriptWithUserGestureForTests(ASCIIToUTF16(dont_fork_popup
));
1220 // Wait for popup window to appear and finish navigating.
1221 popup_observer
.Wait();
1222 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1223 WebContents
* newtab
= browser()->tab_strip_model()->GetActiveWebContents();
1224 EXPECT_TRUE(newtab
);
1225 EXPECT_NE(oldtab
, newtab
);
1226 nav_observer
.Wait();
1227 ASSERT_TRUE(newtab
->GetController().GetLastCommittedEntry());
1228 EXPECT_EQ(https_url
.spec(),
1229 newtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1231 // Popup window should still be in the opener's process.
1232 content::RenderProcessHost
* popup_process
=
1233 newtab
->GetRenderProcessHost();
1234 EXPECT_EQ(process
, popup_process
);
1236 // Same thing if the current tab tries to navigate itself.
1237 std::string navigate_str
= "document.location=\"";
1238 navigate_str
+= https_url
.spec();
1239 navigate_str
+= "\";";
1241 content::WindowedNotificationObserver
nav_observer2(
1242 content::NOTIFICATION_NAV_ENTRY_COMMITTED
,
1243 content::NotificationService::AllSources());
1244 oldtab
->GetMainFrame()->ExecuteJavaScriptWithUserGestureForTests(
1245 ASCIIToUTF16(navigate_str
));
1246 nav_observer2
.Wait();
1247 ASSERT_TRUE(oldtab
->GetController().GetLastCommittedEntry());
1248 EXPECT_EQ(https_url
.spec(),
1249 oldtab
->GetController().GetLastCommittedEntry()->GetURL().spec());
1251 // Original window should still be in the original process.
1252 content::RenderProcessHost
* new_process
= newtab
->GetRenderProcessHost();
1253 EXPECT_EQ(process
, new_process
);
1256 // Test that get_process_idle_time() returns reasonable values when compared
1257 // with time deltas measured locally.
1258 IN_PROC_BROWSER_TEST_F(BrowserTest
, RenderIdleTime
) {
1259 base::TimeTicks start
= base::TimeTicks::Now();
1260 ui_test_utils::NavigateToURL(
1261 browser(), ui_test_utils::GetTestUrl(
1262 base::FilePath(base::FilePath::kCurrentDirectory
),
1263 base::FilePath(kTitle1File
)));
1264 content::RenderProcessHost::iterator
it(
1265 content::RenderProcessHost::AllHostsIterator());
1266 for (; !it
.IsAtEnd(); it
.Advance()) {
1267 base::TimeDelta renderer_td
=
1268 it
.GetCurrentValue()->GetChildProcessIdleTime();
1269 base::TimeDelta browser_td
= base::TimeTicks::Now() - start
;
1270 EXPECT_TRUE(browser_td
>= renderer_td
);
1274 // Test IDC_CREATE_SHORTCUTS command is enabled for url scheme file, ftp, http
1275 // and https and disabled for chrome://, about:// etc.
1276 // TODO(pinkerton): Disable app-mode in the model until we implement it
1277 // on the Mac. http://crbug.com/13148
1278 #if !defined(OS_MACOSX)
1279 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutFile
) {
1280 CommandUpdater
* command_updater
=
1281 browser()->command_controller()->command_updater();
1283 static const base::FilePath::CharType
* kEmptyFile
=
1284 FILE_PATH_LITERAL("empty.html");
1285 GURL
file_url(ui_test_utils::GetTestUrl(base::FilePath(
1286 base::FilePath::kCurrentDirectory
), base::FilePath(kEmptyFile
)));
1287 ASSERT_TRUE(file_url
.SchemeIs(url::kFileScheme
));
1288 ui_test_utils::NavigateToURL(browser(), file_url
);
1289 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1292 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutHttp
) {
1293 CommandUpdater
* command_updater
=
1294 browser()->command_controller()->command_updater();
1296 ASSERT_TRUE(test_server()->Start());
1297 GURL
http_url(test_server()->GetURL(std::string()));
1298 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1299 ui_test_utils::NavigateToURL(browser(), http_url
);
1300 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1303 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutHttps
) {
1304 CommandUpdater
* command_updater
=
1305 browser()->command_controller()->command_updater();
1307 net::SpawnedTestServer
test_server(net::SpawnedTestServer::TYPE_HTTPS
,
1308 net::SpawnedTestServer::kLocalhost
,
1309 base::FilePath(kDocRoot
));
1310 ASSERT_TRUE(test_server
.Start());
1311 GURL
https_url(test_server
.GetURL("/"));
1312 ASSERT_TRUE(https_url
.SchemeIs(url::kHttpsScheme
));
1313 ui_test_utils::NavigateToURL(browser(), https_url
);
1314 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1317 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutFtp
) {
1318 CommandUpdater
* command_updater
=
1319 browser()->command_controller()->command_updater();
1321 net::SpawnedTestServer
test_server(net::SpawnedTestServer::TYPE_FTP
,
1322 net::SpawnedTestServer::kLocalhost
,
1323 base::FilePath(kDocRoot
));
1324 ASSERT_TRUE(test_server
.Start());
1325 GURL
ftp_url(test_server
.GetURL(std::string()));
1326 ASSERT_TRUE(ftp_url
.SchemeIs(url::kFtpScheme
));
1327 ui_test_utils::NavigateToURL(browser(), ftp_url
);
1328 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1331 IN_PROC_BROWSER_TEST_F(BrowserTest
, CommandCreateAppShortcutInvalid
) {
1332 CommandUpdater
* command_updater
=
1333 browser()->command_controller()->command_updater();
1335 // Urls that should not have shortcuts.
1336 GURL
new_tab_url(chrome::kChromeUINewTabURL
);
1337 ui_test_utils::NavigateToURL(browser(), new_tab_url
);
1338 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1340 GURL
history_url(chrome::kChromeUIHistoryURL
);
1341 ui_test_utils::NavigateToURL(browser(), history_url
);
1342 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1344 GURL
blank_url(url::kAboutBlankURL
);
1345 ui_test_utils::NavigateToURL(browser(), blank_url
);
1346 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_CREATE_SHORTCUTS
));
1349 // Change a tab into an application window.
1350 // DISABLED: http://crbug.com/72310
1351 IN_PROC_BROWSER_TEST_F(BrowserTest
, DISABLED_ConvertTabToAppShortcut
) {
1352 ASSERT_TRUE(test_server()->Start());
1353 GURL
http_url(test_server()->GetURL(std::string()));
1354 ASSERT_TRUE(http_url
.SchemeIs(url::kHttpScheme
));
1356 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1357 WebContents
* initial_tab
= browser()->tab_strip_model()->GetWebContentsAt(0);
1358 WebContents
* app_tab
= chrome::AddSelectedTabWithURL(
1359 browser(), http_url
, ui::PAGE_TRANSITION_TYPED
);
1360 ASSERT_EQ(2, browser()->tab_strip_model()->count());
1361 ASSERT_EQ(1u, chrome::GetBrowserCount(browser()->profile(),
1362 browser()->host_desktop_type()));
1364 // Normal tabs should accept load drops.
1365 EXPECT_TRUE(initial_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1366 EXPECT_TRUE(app_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1368 // Turn |app_tab| into a tab in an app panel.
1369 chrome::ConvertTabToAppWindow(browser(), app_tab
);
1371 // The launch should have created a new browser.
1372 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1373 browser()->host_desktop_type()));
1375 // Find the new browser.
1376 Browser
* app_browser
= NULL
;
1377 for (chrome::BrowserIterator it
; !it
.done() && !app_browser
; it
.Next()) {
1378 if (*it
!= browser())
1381 ASSERT_TRUE(app_browser
);
1383 // Check that the tab contents is in the new browser, and not in the old.
1384 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1385 ASSERT_EQ(initial_tab
, browser()->tab_strip_model()->GetWebContentsAt(0));
1387 // Check that the appliaction browser has a single tab, and that tab contains
1388 // the content that we app-ified.
1389 ASSERT_EQ(1, app_browser
->tab_strip_model()->count());
1390 ASSERT_EQ(app_tab
, app_browser
->tab_strip_model()->GetWebContentsAt(0));
1392 // Normal tabs should accept load drops.
1393 EXPECT_TRUE(initial_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1395 // The tab in an app window should not.
1396 EXPECT_FALSE(app_tab
->GetMutableRendererPrefs()->can_accept_load_drops
);
1399 #endif // !defined(OS_MACOSX)
1401 // Test RenderView correctly send back favicon url for web page that redirects
1402 // to an anchor in javascript body.onload handler.
1403 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1404 DISABLED_FaviconOfOnloadRedirectToAnchorPage
) {
1405 ASSERT_TRUE(test_server()->Start());
1406 GURL
url(test_server()->GetURL("files/onload_redirect_to_anchor.html"));
1407 GURL
expected_favicon_url(test_server()->GetURL("files/test.png"));
1409 ui_test_utils::NavigateToURL(browser(), url
);
1411 NavigationEntry
* entry
= browser()->tab_strip_model()->
1412 GetActiveWebContents()->GetController().GetLastCommittedEntry();
1413 EXPECT_EQ(expected_favicon_url
.spec(), entry
->GetFavicon().url
.spec());
1416 #if defined(OS_MACOSX) || defined(OS_LINUX) || defined (OS_WIN)
1417 // http://crbug.com/83828. On Mac 10.6, the failure rate is 14%
1418 #define MAYBE_FaviconChange DISABLED_FaviconChange
1420 #define MAYBE_FaviconChange FaviconChange
1422 // Test that an icon can be changed from JS.
1423 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_FaviconChange
) {
1424 static const base::FilePath::CharType
* kFile
=
1425 FILE_PATH_LITERAL("onload_change_favicon.html");
1426 GURL
file_url(ui_test_utils::GetTestUrl(base::FilePath(
1427 base::FilePath::kCurrentDirectory
), base::FilePath(kFile
)));
1428 ASSERT_TRUE(file_url
.SchemeIs(url::kFileScheme
));
1429 ui_test_utils::NavigateToURL(browser(), file_url
);
1431 NavigationEntry
* entry
= browser()->tab_strip_model()->
1432 GetActiveWebContents()->GetController().GetLastCommittedEntry();
1433 static const base::FilePath::CharType
* kIcon
=
1434 FILE_PATH_LITERAL("test1.png");
1435 GURL
expected_favicon_url(ui_test_utils::GetTestUrl(base::FilePath(
1436 base::FilePath::kCurrentDirectory
), base::FilePath(kIcon
)));
1437 EXPECT_EQ(expected_favicon_url
.spec(), entry
->GetFavicon().url
.spec());
1440 // http://crbug.com/172336
1442 #define MAYBE_TabClosingWhenRemovingExtension \
1443 DISABLED_TabClosingWhenRemovingExtension
1445 #define MAYBE_TabClosingWhenRemovingExtension TabClosingWhenRemovingExtension
1447 // Makes sure TabClosing is sent when uninstalling an extension that is an app
1449 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_TabClosingWhenRemovingExtension
) {
1450 ASSERT_TRUE(test_server()->Start());
1451 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1452 GURL
url(test_server()->GetURL("empty.html"));
1453 TabStripModel
* model
= browser()->tab_strip_model();
1455 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1457 const Extension
* extension_app
= GetExtension();
1459 ui_test_utils::NavigateToURL(browser(), url
);
1461 WebContents
* app_contents
= WebContents::Create(
1462 WebContents::CreateParams(browser()->profile()));
1463 extensions::TabHelper::CreateForWebContents(app_contents
);
1464 extensions::TabHelper
* extensions_tab_helper
=
1465 extensions::TabHelper::FromWebContents(app_contents
);
1466 extensions_tab_helper
->SetExtensionApp(extension_app
);
1468 model
->AddWebContents(app_contents
, 0, ui::PageTransitionFromInt(0),
1469 TabStripModel::ADD_NONE
);
1470 model
->SetTabPinned(0, true);
1471 ui_test_utils::NavigateToURL(browser(), url
);
1473 MockTabStripModelObserver observer
;
1474 model
->AddObserver(&observer
);
1476 // Uninstall the extension and make sure TabClosing is sent.
1477 ExtensionService
* service
= extensions::ExtensionSystem::Get(
1478 browser()->profile())->extension_service();
1479 service
->UninstallExtension(GetExtension()->id(),
1480 extensions::UNINSTALL_REASON_FOR_TESTING
,
1481 base::Bind(&base::DoNothing
),
1483 EXPECT_EQ(1, observer
.closing_count());
1485 model
->RemoveObserver(&observer
);
1487 // There should only be one tab now.
1488 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1491 // Open with --app-id=<id>, and see that an application tab opens by default.
1492 IN_PROC_BROWSER_TEST_F(BrowserTest
, AppIdSwitch
) {
1493 ASSERT_TRUE(test_server()->Start());
1495 // There should be one tab to start with.
1496 ASSERT_EQ(1, browser()->tab_strip_model()->count());
1499 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1500 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1501 const Extension
* extension_app
= GetExtension();
1503 base::CommandLine
command_line(base::CommandLine::NO_PROGRAM
);
1504 command_line
.AppendSwitchASCII(switches::kAppId
, extension_app
->id());
1506 chrome::startup::IsFirstRun first_run
= first_run::IsChromeFirstRun() ?
1507 chrome::startup::IS_FIRST_RUN
: chrome::startup::IS_NOT_FIRST_RUN
;
1508 StartupBrowserCreatorImpl
launch(base::FilePath(), command_line
, first_run
);
1510 bool new_bookmark_apps_enabled
= extensions::util::IsNewBookmarkAppsEnabled();
1512 // If the new bookmark app flow is enabled, the app should open as an tab.
1513 // Otherwise the app should open as an app window.
1514 EXPECT_EQ(!new_bookmark_apps_enabled
,
1515 launch
.OpenApplicationWindow(browser()->profile()));
1516 EXPECT_EQ(new_bookmark_apps_enabled
,
1517 launch
.OpenApplicationTab(browser()->profile()));
1519 // Check that a the number of browsers and tabs is correct.
1520 unsigned int expected_browsers
= 1;
1521 int expected_tabs
= 1;
1522 new_bookmark_apps_enabled
? expected_tabs
++ : expected_browsers
++;
1524 EXPECT_EQ(expected_browsers
,
1525 chrome::GetBrowserCount(browser()->profile(),
1526 browser()->host_desktop_type()));
1527 EXPECT_EQ(expected_tabs
, browser()->tab_strip_model()->count());
1530 // Open an app window and the dev tools window and ensure that the location
1531 // bar settings are correct.
1532 IN_PROC_BROWSER_TEST_F(BrowserTest
, ShouldShowLocationBar
) {
1533 ASSERT_TRUE(test_server()->Start());
1536 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1537 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1538 const Extension
* extension_app
= GetExtension();
1540 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1541 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1542 browser()->profile(), extension_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1543 NEW_WINDOW
, extensions::SOURCE_TEST
));
1544 ASSERT_TRUE(app_window
);
1546 DevToolsWindow
* devtools_window
=
1547 DevToolsWindowTesting::OpenDevToolsWindowSync(browser(), false);
1549 // The launch should have created a new app browser and a dev tools browser.
1551 chrome::GetBrowserCount(browser()->profile(),
1552 browser()->host_desktop_type()));
1554 // Find the new browsers.
1555 Browser
* app_browser
= NULL
;
1556 Browser
* dev_tools_browser
= NULL
;
1557 for (chrome::BrowserIterator it
; !it
.done(); it
.Next()) {
1558 if (*it
== browser()) {
1560 } else if ((*it
)->app_name() == DevToolsWindow::kDevToolsApp
) {
1561 dev_tools_browser
= *it
;
1566 ASSERT_TRUE(dev_tools_browser
);
1567 ASSERT_TRUE(app_browser
);
1568 ASSERT_TRUE(app_browser
!= browser());
1571 dev_tools_browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
1573 // App windows can show location bars, for example when they navigate away
1574 // from their starting origin.
1576 app_browser
->SupportsWindowFeature(Browser::FEATURE_LOCATIONBAR
));
1578 DevToolsWindowTesting::CloseDevToolsWindowSync(devtools_window
);
1581 // Tests that the CLD (Compact Language Detection) works properly.
1582 IN_PROC_BROWSER_TEST_F(BrowserTest
, PageLanguageDetection
) {
1583 scoped_ptr
<test::CldDataHarness
> cld_data_harness
=
1584 test::CldDataHarnessFactory::Get()->CreateCldDataHarness();
1585 ASSERT_NO_FATAL_FAILURE(cld_data_harness
->Init());
1586 ASSERT_TRUE(test_server()->Start());
1588 translate::LanguageDetectionDetails details
;
1590 // Open a new tab with a page in English.
1591 AddTabAtIndex(0, GURL(test_server()->GetURL("files/english_page.html")),
1592 ui::PAGE_TRANSITION_TYPED
);
1594 WebContents
* current_web_contents
=
1595 browser()->tab_strip_model()->GetActiveWebContents();
1596 ChromeTranslateClient
* chrome_translate_client
=
1597 ChromeTranslateClient::FromWebContents(current_web_contents
);
1598 content::Source
<WebContents
> source(current_web_contents
);
1600 ui_test_utils::WindowedNotificationObserverWithDetails
<
1601 translate::LanguageDetectionDetails
>
1602 en_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1605 chrome_translate_client
->GetLanguageState().original_language());
1606 en_language_detected_signal
.Wait();
1607 EXPECT_TRUE(en_language_detected_signal
.GetDetailsFor(
1608 source
.map_key(), &details
));
1609 EXPECT_EQ("en", details
.adopted_language
);
1611 chrome_translate_client
->GetLanguageState().original_language());
1613 // Now navigate to a page in French.
1614 ui_test_utils::WindowedNotificationObserverWithDetails
<
1615 translate::LanguageDetectionDetails
>
1616 fr_language_detected_signal(chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED
,
1618 ui_test_utils::NavigateToURL(
1619 browser(), GURL(test_server()->GetURL("files/french_page.html")));
1620 fr_language_detected_signal
.Wait();
1621 details
.adopted_language
.clear();
1622 EXPECT_TRUE(fr_language_detected_signal
.GetDetailsFor(
1623 source
.map_key(), &details
));
1624 EXPECT_EQ("fr", details
.adopted_language
);
1626 chrome_translate_client
->GetLanguageState().original_language());
1629 // Chromeos defaults to restoring the last session, so this test isn't
1631 #if !defined(OS_CHROMEOS)
1632 #if defined(OS_MACOSX)
1633 // Crashy, http://crbug.com/38522
1634 #define RestorePinnedTabs DISABLED_RestorePinnedTabs
1636 // Makes sure pinned tabs are restored correctly on start.
1637 IN_PROC_BROWSER_TEST_F(BrowserTest
, RestorePinnedTabs
) {
1638 ASSERT_TRUE(test_server()->Start());
1640 // Add a pinned tab.
1641 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1642 GURL
url(test_server()->GetURL("empty.html"));
1643 TabStripModel
* model
= browser()->tab_strip_model();
1644 ui_test_utils::NavigateToURL(browser(), url
);
1645 model
->SetTabPinned(0, true);
1647 // Add a non pinned tab.
1648 chrome::NewTab(browser());
1649 ui_test_utils::NavigateToURL(browser(), url
);
1651 // Add another pinned tab.
1652 chrome::NewTab(browser());
1653 ui_test_utils::NavigateToURL(browser(), GURL(url::kAboutBlankURL
));
1654 model
->SetTabPinned(2, true);
1656 // Write out the pinned tabs.
1657 PinnedTabCodec::WritePinnedTabs(browser()->profile());
1659 // Simulate launching again.
1660 base::CommandLine
dummy(base::CommandLine::NO_PROGRAM
);
1661 chrome::startup::IsFirstRun first_run
= first_run::IsChromeFirstRun() ?
1662 chrome::startup::IS_FIRST_RUN
: chrome::startup::IS_NOT_FIRST_RUN
;
1663 StartupBrowserCreatorImpl
launch(base::FilePath(), dummy
, first_run
);
1664 launch
.profile_
= browser()->profile();
1665 launch
.ProcessStartupURLs(std::vector
<GURL
>(),
1666 browser()->host_desktop_type());
1668 // The launch should have created a new browser.
1669 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1670 browser()->host_desktop_type()));
1672 // Find the new browser.
1673 Browser
* new_browser
= NULL
;
1674 for (chrome::BrowserIterator it
; !it
.done() && !new_browser
; it
.Next()) {
1675 if (*it
!= browser())
1678 ASSERT_TRUE(new_browser
);
1679 ASSERT_TRUE(new_browser
!= browser());
1681 // We should get back an additional tab for the app, and another for the
1682 // default home page.
1683 ASSERT_EQ(3, new_browser
->tab_strip_model()->count());
1685 // Make sure the state matches.
1686 TabStripModel
* new_model
= new_browser
->tab_strip_model();
1687 EXPECT_TRUE(new_model
->IsTabPinned(0));
1688 EXPECT_TRUE(new_model
->IsTabPinned(1));
1689 EXPECT_FALSE(new_model
->IsTabPinned(2));
1691 EXPECT_EQ(GURL(chrome::kChromeUINewTabURL
),
1692 new_model
->GetWebContentsAt(2)->GetURL());
1694 #endif // !defined(OS_CHROMEOS)
1696 // This test verifies we don't crash when closing the last window and the app
1698 IN_PROC_BROWSER_TEST_F(BrowserTest
, CloseWithAppMenuOpen
) {
1699 if (browser_defaults::kBrowserAliveWithNoWindows
)
1702 // We need a message loop running for menus on windows.
1703 base::MessageLoop::current()->task_runner()->PostTask(
1704 FROM_HERE
, base::Bind(&RunCloseWithAppMenuCallback
, browser()));
1707 #if !defined(OS_MACOSX)
1708 IN_PROC_BROWSER_TEST_F(BrowserTest
, OpenAppWindowLikeNtp
) {
1709 ASSERT_TRUE(test_server()->Start());
1712 host_resolver()->AddRule("www.example.com", "127.0.0.1");
1713 ASSERT_TRUE(LoadExtension(test_data_dir_
.AppendASCII("app/")));
1714 const Extension
* extension_app
= GetExtension();
1716 // Launch it in a window, as AppLauncherHandler::HandleLaunchApp() would.
1717 WebContents
* app_window
= OpenApplication(AppLaunchParams(
1718 browser()->profile(), extension_app
, extensions::LAUNCH_CONTAINER_WINDOW
,
1719 NEW_WINDOW
, extensions::SOURCE_TEST
));
1720 ASSERT_TRUE(app_window
);
1722 // Apps launched in a window from the NTP have an extensions tab helper but
1723 // do not have extension_app set in it.
1724 ASSERT_TRUE(extensions::TabHelper::FromWebContents(app_window
));
1726 extensions::TabHelper::FromWebContents(app_window
)->extension_app());
1727 EXPECT_EQ(extensions::AppLaunchInfo::GetFullLaunchURL(extension_app
),
1728 app_window
->GetURL());
1730 // The launch should have created a new browser.
1731 ASSERT_EQ(2u, chrome::GetBrowserCount(browser()->profile(),
1732 browser()->host_desktop_type()));
1734 // Find the new browser.
1735 Browser
* new_browser
= NULL
;
1736 for (chrome::BrowserIterator it
; !it
.done() && !new_browser
; it
.Next()) {
1737 if (*it
!= browser())
1740 ASSERT_TRUE(new_browser
);
1741 ASSERT_TRUE(new_browser
!= browser());
1743 EXPECT_TRUE(new_browser
->is_app());
1745 // The browser's app name should include the extension's id.
1746 std::string app_name
= new_browser
->app_name_
;
1747 EXPECT_NE(app_name
.find(extension_app
->id()), std::string::npos
)
1748 << "Name " << app_name
<< " should contain id "<< extension_app
->id();
1750 #endif // !defined(OS_MACOSX)
1752 // Makes sure the browser doesn't crash when
1753 // set_show_state(ui::SHOW_STATE_MAXIMIZED) has been invoked.
1754 IN_PROC_BROWSER_TEST_F(BrowserTest
, StartMaximized
) {
1755 Browser::Type types
[] = { Browser::TYPE_TABBED
, Browser::TYPE_POPUP
};
1756 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
1757 Browser::CreateParams
params(types
[i
], browser()->profile(),
1758 browser()->host_desktop_type());
1759 params
.initial_show_state
= ui::SHOW_STATE_MAXIMIZED
;
1760 AddBlankTabAndShow(new Browser(params
));
1764 // Aura doesn't support minimized window. crbug.com/104571.
1765 #if defined(USE_AURA)
1766 #define MAYBE_StartMinimized DISABLED_StartMinimized
1768 #define MAYBE_StartMinimized StartMinimized
1770 // Makes sure the browser doesn't crash when
1771 // set_show_state(ui::SHOW_STATE_MINIMIZED) has been invoked.
1772 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_StartMinimized
) {
1773 Browser::Type types
[] = { Browser::TYPE_TABBED
, Browser::TYPE_POPUP
};
1774 for (size_t i
= 0; i
< arraysize(types
); ++i
) {
1775 Browser::CreateParams
params(types
[i
], browser()->profile(),
1776 browser()->host_desktop_type());
1777 params
.initial_show_state
= ui::SHOW_STATE_MINIMIZED
;
1778 AddBlankTabAndShow(new Browser(params
));
1782 // Makes sure the forward button is disabled immediately when navigating
1783 // forward to a slow-to-commit page.
1784 IN_PROC_BROWSER_TEST_F(BrowserTest
, ForwardDisabledOnForward
) {
1785 GURL
blank_url(url::kAboutBlankURL
);
1786 ui_test_utils::NavigateToURL(browser(), blank_url
);
1788 ui_test_utils::NavigateToURL(
1789 browser(), ui_test_utils::GetTestUrl(
1790 base::FilePath(base::FilePath::kCurrentDirectory
),
1791 base::FilePath(kTitle1File
)));
1793 content::WindowedNotificationObserver
back_nav_load_observer(
1794 content::NOTIFICATION_LOAD_STOP
,
1795 content::Source
<NavigationController
>(
1796 &browser()->tab_strip_model()->GetActiveWebContents()->
1798 chrome::GoBack(browser(), CURRENT_TAB
);
1799 back_nav_load_observer
.Wait();
1800 CommandUpdater
* command_updater
=
1801 browser()->command_controller()->command_updater();
1802 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_FORWARD
));
1804 content::WindowedNotificationObserver
forward_nav_load_observer(
1805 content::NOTIFICATION_LOAD_STOP
,
1806 content::Source
<NavigationController
>(
1807 &browser()->tab_strip_model()->GetActiveWebContents()->
1809 chrome::GoForward(browser(), CURRENT_TAB
);
1810 // This check will happen before the navigation completes, since the browser
1811 // won't process the renderer's response until the Wait() call below.
1812 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_FORWARD
));
1813 forward_nav_load_observer
.Wait();
1816 // Makes sure certain commands are disabled when Incognito mode is forced.
1817 IN_PROC_BROWSER_TEST_F(BrowserTest
, DisableMenuItemsWhenIncognitoIsForced
) {
1818 CommandUpdater
* command_updater
=
1819 browser()->command_controller()->command_updater();
1820 // At the beginning, all commands are enabled.
1821 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1822 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1823 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1824 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1825 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1826 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1828 // Set Incognito to FORCED.
1829 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1830 IncognitoModePrefs::FORCED
);
1831 // Bookmarks & Settings commands should get disabled.
1832 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1833 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1834 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1835 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1836 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1837 // New Incognito Window command, however, should be enabled.
1838 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1840 // Create a new browser.
1841 Browser
* new_browser
=
1842 new Browser(Browser::CreateParams(
1843 browser()->profile()->GetOffTheRecordProfile(),
1844 browser()->host_desktop_type()));
1845 CommandUpdater
* new_command_updater
=
1846 new_browser
->command_controller()->command_updater();
1847 // It should have Bookmarks & Settings commands disabled by default.
1848 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1849 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(
1850 IDC_SHOW_BOOKMARK_MANAGER
));
1851 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1852 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1853 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1854 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1857 // Makes sure New Incognito Window command is disabled when Incognito mode is
1859 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1860 NoNewIncognitoWindowWhenIncognitoIsDisabled
) {
1861 CommandUpdater
* command_updater
=
1862 browser()->command_controller()->command_updater();
1863 // Set Incognito to DISABLED.
1864 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1865 IncognitoModePrefs::DISABLED
);
1866 // Make sure New Incognito Window command is disabled. All remaining commands
1867 // should be enabled.
1868 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1869 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1870 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1871 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1872 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1873 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1875 // Create a new browser.
1876 Browser
* new_browser
=
1877 new Browser(Browser::CreateParams(browser()->profile(),
1878 browser()->host_desktop_type()));
1879 CommandUpdater
* new_command_updater
=
1880 new_browser
->command_controller()->command_updater();
1881 EXPECT_FALSE(new_command_updater
->IsCommandEnabled(IDC_NEW_INCOGNITO_WINDOW
));
1882 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1883 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1884 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1885 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1886 EXPECT_TRUE(new_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1889 // Makes sure Extensions and Settings commands are disabled in certain
1890 // circumstances even though normally they should stay enabled.
1891 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1892 DisableExtensionsAndSettingsWhenIncognitoIsDisabled
) {
1893 CommandUpdater
* command_updater
=
1894 browser()->command_controller()->command_updater();
1895 // Disable extensions. This should disable Extensions menu.
1896 extensions::ExtensionSystem::Get(browser()->profile())->extension_service()->
1897 set_extensions_enabled(false);
1898 // Set Incognito to DISABLED.
1899 IncognitoModePrefs::SetAvailability(browser()->profile()->GetPrefs(),
1900 IncognitoModePrefs::DISABLED
);
1901 // Make sure Manage Extensions command is disabled.
1902 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1903 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_NEW_WINDOW
));
1904 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SHOW_BOOKMARK_MANAGER
));
1905 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1906 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1908 // Create a popup (non-main-UI-type) browser. Settings command as well
1909 // as Extensions should be disabled.
1910 Browser
* popup_browser
= new Browser(
1911 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
1912 browser()->host_desktop_type()));
1913 CommandUpdater
* popup_command_updater
=
1914 popup_browser
->command_controller()->command_updater();
1915 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_MANAGE_EXTENSIONS
));
1916 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1917 EXPECT_TRUE(popup_command_updater
->IsCommandEnabled(
1918 IDC_SHOW_BOOKMARK_MANAGER
));
1919 EXPECT_FALSE(popup_command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1922 // Makes sure Extensions and Settings commands are disabled in certain
1923 // circumstances even though normally they should stay enabled.
1924 IN_PROC_BROWSER_TEST_F(BrowserTest
,
1925 DisableOptionsAndImportMenuItemsConsistently
) {
1926 // Create a popup browser.
1927 Browser
* popup_browser
= new Browser(
1928 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile(),
1929 browser()->host_desktop_type()));
1930 CommandUpdater
* command_updater
=
1931 popup_browser
->command_controller()->command_updater();
1932 // OPTIONS and IMPORT_SETTINGS are disabled for a non-normal UI.
1933 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1934 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1936 // Set Incognito to FORCED.
1937 IncognitoModePrefs::SetAvailability(popup_browser
->profile()->GetPrefs(),
1938 IncognitoModePrefs::FORCED
);
1939 // OPTIONS and IMPORT_SETTINGS are disabled when Incognito is forced.
1940 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1941 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1942 // Set Incognito to AVAILABLE.
1943 IncognitoModePrefs::SetAvailability(popup_browser
->profile()->GetPrefs(),
1944 IncognitoModePrefs::ENABLED
);
1945 // OPTIONS and IMPORT_SETTINGS are still disabled since it is a non-normal UI.
1946 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_OPTIONS
));
1947 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_IMPORT_SETTINGS
));
1952 void OnZoomLevelChanged(const base::Closure
& callback
,
1953 const HostZoomMap::ZoomLevelChange
& host
) {
1960 // Flakes regularly on Windows XP
1961 // http://crbug.com/146040
1962 #define MAYBE_PageZoom DISABLED_PageZoom
1964 #define MAYBE_PageZoom PageZoom
1969 int GetZoomPercent(const content::WebContents
* contents
,
1971 bool* enable_minus
) {
1973 ui_zoom::ZoomController::FromWebContents(contents
)->GetZoomPercent();
1974 *enable_plus
= percent
< contents
->GetMaximumZoomPercent();
1975 *enable_minus
= percent
> contents
->GetMinimumZoomPercent();
1981 IN_PROC_BROWSER_TEST_F(BrowserTest
, MAYBE_PageZoom
) {
1982 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
1983 bool enable_plus
, enable_minus
;
1986 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
1987 new content::MessageLoopRunner
);
1988 content::HostZoomMap::ZoomLevelChangedCallback
callback(
1989 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
1990 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
1991 content::HostZoomMap::GetDefaultForBrowserContext(
1992 browser()->profile())->AddZoomLevelChangedCallback(callback
);
1993 chrome::Zoom(browser(), content::PAGE_ZOOM_IN
);
1996 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 110);
1997 EXPECT_TRUE(enable_plus
);
1998 EXPECT_TRUE(enable_minus
);
2002 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2003 new content::MessageLoopRunner
);
2004 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2005 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2006 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2007 content::HostZoomMap::GetDefaultForBrowserContext(
2008 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2009 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET
);
2012 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 100);
2013 EXPECT_TRUE(enable_plus
);
2014 EXPECT_TRUE(enable_minus
);
2018 scoped_refptr
<content::MessageLoopRunner
> loop_runner(
2019 new content::MessageLoopRunner
);
2020 content::HostZoomMap::ZoomLevelChangedCallback
callback(
2021 base::Bind(&OnZoomLevelChanged
, loop_runner
->QuitClosure()));
2022 scoped_ptr
<content::HostZoomMap::Subscription
> sub
=
2023 content::HostZoomMap::GetDefaultForBrowserContext(
2024 browser()->profile())->AddZoomLevelChangedCallback(callback
);
2025 chrome::Zoom(browser(), content::PAGE_ZOOM_OUT
);
2028 EXPECT_EQ(GetZoomPercent(contents
, &enable_plus
, &enable_minus
), 90);
2029 EXPECT_TRUE(enable_plus
);
2030 EXPECT_TRUE(enable_minus
);
2033 chrome::Zoom(browser(), content::PAGE_ZOOM_RESET
);
2036 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCommandDisable
) {
2037 ASSERT_TRUE(test_server()->Start());
2038 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2039 GURL
url(test_server()->GetURL("empty.html"));
2040 ui_test_utils::NavigateToURL(browser(), url
);
2042 CommandUpdater
* command_updater
=
2043 browser()->command_controller()->command_updater();
2044 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2045 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2046 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2047 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2048 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_DUPLICATE_TAB
));
2050 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2052 TestInterstitialPage
* interstitial
=
2053 new TestInterstitialPage(contents
, false, GURL());
2054 content::WaitForInterstitialAttach(contents
);
2056 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2058 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2059 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2060 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2061 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2062 EXPECT_FALSE(command_updater
->IsCommandEnabled(IDC_DUPLICATE_TAB
));
2064 // Proceed and wait for interstitial to detach. This doesn't destroy
2066 interstitial
->Proceed();
2067 content::WaitForInterstitialDetach(contents
);
2068 // interstitial is deleted now.
2070 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_VIEW_SOURCE
));
2071 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_PRINT
));
2072 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_SAVE_PAGE
));
2073 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_ENCODING_MENU
));
2074 EXPECT_TRUE(command_updater
->IsCommandEnabled(IDC_DUPLICATE_TAB
));
2077 // Ensure that creating an interstitial page closes any JavaScript dialogs
2078 // that were present on the previous page. See http://crbug.com/295695.
2079 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialClosesDialogs
) {
2080 ASSERT_TRUE(test_server()->Start());
2081 host_resolver()->AddRule("www.example.com", "127.0.0.1");
2082 GURL
url(test_server()->GetURL("empty.html"));
2083 ui_test_utils::NavigateToURL(browser(), url
);
2085 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2086 contents
->GetMainFrame()->ExecuteJavaScriptForTests(
2087 ASCIIToUTF16("alert('Dialog showing!');"));
2088 AppModalDialog
* alert
= ui_test_utils::WaitForAppModalDialog();
2089 EXPECT_TRUE(alert
->IsValid());
2090 AppModalDialogQueue
* dialog_queue
= AppModalDialogQueue::GetInstance();
2091 EXPECT_TRUE(dialog_queue
->HasActiveDialog());
2093 TestInterstitialPage
* interstitial
=
2094 new TestInterstitialPage(contents
, false, GURL());
2095 content::WaitForInterstitialAttach(contents
);
2097 // The interstitial should have closed the dialog.
2098 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2099 EXPECT_FALSE(dialog_queue
->HasActiveDialog());
2101 // Don't proceed and wait for interstitial to detach. This doesn't destroy
2103 interstitial
->DontProceed();
2104 content::WaitForInterstitialDetach(contents
);
2105 // interstitial is deleted now.
2107 // Make sure input events still work in the renderer process.
2108 EXPECT_FALSE(contents
->GetRenderProcessHost()->IgnoreInputEvents());
2112 IN_PROC_BROWSER_TEST_F(BrowserTest
, InterstitialCloseTab
) {
2113 WebContents
* contents
= browser()->tab_strip_model()->GetActiveWebContents();
2115 // Interstitial will delete itself when we close the tab.
2116 new TestInterstitialPage(contents
, false, GURL());
2117 content::WaitForInterstitialAttach(contents
);
2119 EXPECT_TRUE(contents
->ShowingInterstitialPage());
2121 // Close the tab and wait for interstitial detach. This destroys |contents|.
2122 content::RunTaskAndWaitForInterstitialDetach(
2123 contents
, base::Bind(&chrome::CloseTab
, browser()));
2124 // interstitial is deleted now.
2127 class MockWebContentsObserver
: public WebContentsObserver
{
2129 explicit MockWebContentsObserver(WebContents
* web_contents
)
2130 : WebContentsObserver(web_contents
),
2131 got_user_gesture_(false) {
2134 void DidGetUserGesture() override
{ got_user_gesture_
= true; }
2136 bool got_user_gesture() const {
2137 return got_user_gesture_
;
2140 void set_got_user_gesture(bool got_it
) {
2141 got_user_gesture_
= got_it
;
2145 bool got_user_gesture_
;
2147 DISALLOW_COPY_AND_ASSIGN(MockWebContentsObserver
);
2150 IN_PROC_BROWSER_TEST_F(BrowserTest
, UserGesturesReported
) {
2151 // Regression test for http://crbug.com/110707. Also tests that a user
2152 // gesture is sent when a normal navigation (via e.g. the omnibox) is
2154 WebContents
* web_contents
=
2155 browser()->tab_strip_model()->GetActiveWebContents();
2156 MockWebContentsObserver
mock_observer(web_contents
);
2158 ASSERT_TRUE(test_server()->Start());
2159 GURL
url(test_server()->GetURL("empty.html"));
2161 ui_test_utils::NavigateToURL(browser(), url
);
2162 EXPECT_TRUE(mock_observer
.got_user_gesture());
2164 mock_observer
.set_got_user_gesture(false);
2165 chrome::Reload(browser(), CURRENT_TAB
);
2166 EXPECT_TRUE(mock_observer
.got_user_gesture());
2169 // TODO(ben): this test was never enabled. It has bit-rotted since being added.
2170 // It originally lived in browser_unittest.cc, but has been moved here to make
2171 // room for real browser unit tests.
2173 class BrowserTest2
: public InProcessBrowserTest
{
2176 host_resolver_proc_
= new net::RuleBasedHostResolverProc(NULL
);
2177 // Avoid making external DNS lookups. In this test we don't need this
2179 host_resolver_proc_
->AddSimulatedFailure("*.google.com");
2180 scoped_host_resolver_proc_
.Init(host_resolver_proc_
.get());
2184 scoped_refptr
<net::RuleBasedHostResolverProc
> host_resolver_proc_
;
2185 net::ScopedDefaultHostResolverProc scoped_host_resolver_proc_
;
2188 IN_PROC_BROWSER_TEST_F(BrowserTest2
, NoTabsInPopups
) {
2189 chrome::RegisterAppPrefs(L
"Test");
2191 // We start with a normal browser with one tab.
2192 EXPECT_EQ(1, browser()->tab_strip_model()->count());
2194 // Open a popup browser with a single blank foreground tab.
2195 Browser
* popup_browser
= new Browser(
2196 Browser::CreateParams(Browser::TYPE_POPUP
, browser()->profile()));
2197 chrome::AddTabAt(popup_browser
, GURL(), -1, true);
2198 EXPECT_EQ(1, popup_browser
->tab_strip_model()->count());
2200 // Now try opening another tab in the popup browser.
2201 AddTabWithURLParams
params1(url
, ui::PAGE_TRANSITION_TYPED
);
2202 popup_browser
->AddTabWithURL(¶ms1
);
2203 EXPECT_EQ(popup_browser
, params1
.target
);
2205 // The popup should still only have one tab.
2206 EXPECT_EQ(1, popup_browser
->tab_strip_model()->count());
2208 // The normal browser should now have two.
2209 EXPECT_EQ(2, browser()->tab_strip_model()->count());
2211 // Open an app frame browser with a single blank foreground tab.
2212 Browser
* app_browser
= new Browser(Browser::CreateParams::CreateForApp(
2213 L
"Test", browser()->profile(), false));
2214 chrome::AddTabAt(app_browser
, GURL(), -1, true);
2215 EXPECT_EQ(1, app_browser
->tab_strip_model()->count());
2217 // Now try opening another tab in the app browser.
2218 AddTabWithURLParams
params2(GURL(url::kAboutBlankURL
),
2219 ui::PAGE_TRANSITION_TYPED
);
2220 app_browser
->AddTabWithURL(¶ms2
);
2221 EXPECT_EQ(app_browser
, params2
.target
);
2223 // The popup should still only have one tab.
2224 EXPECT_EQ(1, app_browser
->tab_strip_model()->count());
2226 // The normal browser should now have three.
2227 EXPECT_EQ(3, browser()->tab_strip_model()->count());
2229 // Open an app frame popup browser with a single blank foreground tab.
2230 Browser
* app_popup_browser
= new Browser(Browser::CreateParams::CreateForApp(
2231 L
"Test", browser()->profile(), false));
2232 chrome::AddTabAt(app_popup_browser
, GURL(), -1, true);
2233 EXPECT_EQ(1, app_popup_browser
->tab_strip_model()->count());
2235 // Now try opening another tab in the app popup browser.
2236 AddTabWithURLParams
params3(GURL(url::kAboutBlankURL
),
2237 ui::PAGE_TRANSITION_TYPED
);
2238 app_popup_browser
->AddTabWithURL(¶ms3
);
2239 EXPECT_EQ(app_popup_browser
, params3
.target
);
2241 // The popup should still only have one tab.
2242 EXPECT_EQ(1, app_popup_browser
->tab_strip_model()->count());
2244 // The normal browser should now have four.
2245 EXPECT_EQ(4, browser()->tab_strip_model()->count());
2247 // Close the additional browsers.
2248 popup_browser
->tab_strip_model()->CloseAllTabs();
2249 app_browser
->tab_strip_model()->CloseAllTabs();
2250 app_popup_browser
->tab_strip_model()->CloseAllTabs();
2254 IN_PROC_BROWSER_TEST_F(BrowserTest
, WindowOpenClose
) {
2255 base::CommandLine::ForCurrentProcess()->AppendSwitch(
2256 switches::kDisablePopupBlocking
);
2257 GURL url
= ui_test_utils::GetTestUrl(
2258 base::FilePath(), base::FilePath().AppendASCII("window.close.html"));
2260 base::string16 title
= ASCIIToUTF16("Title Of Awesomeness");
2261 content::TitleWatcher
title_watcher(
2262 browser()->tab_strip_model()->GetActiveWebContents(), title
);
2263 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(browser(), url
, 2);
2264 EXPECT_EQ(title
, title_watcher
.WaitAndGetTitle());
2267 // TODO(linux_aura) http://crbug.com/163931
2268 // Mac disabled: http://crbug.com/169820
2269 #if !defined(OS_MACOSX) && \
2270 !(defined(OS_LINUX) && !defined(OS_CHROMEOS) && defined(USE_AURA))
2271 IN_PROC_BROWSER_TEST_F(BrowserTest
, FullscreenBookmarkBar
) {
2272 #if defined(OS_WIN) && defined(USE_ASH)
2273 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2274 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2275 switches::kAshBrowserTests
))
2279 chrome::ToggleBookmarkBar(browser());
2280 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2281 chrome::ToggleFullscreenMode(browser());
2282 EXPECT_TRUE(browser()->window()->IsFullscreen());
2283 #if defined(OS_MACOSX)
2284 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2285 #elif defined(OS_CHROMEOS)
2286 // TODO(jamescook): If immersive fullscreen is disabled by default, test
2287 // for BookmarkBar::HIDDEN.
2288 EXPECT_EQ(BookmarkBar::SHOW
, browser()->bookmark_bar_state());
2290 EXPECT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2295 IN_PROC_BROWSER_TEST_F(BrowserTest
, DisallowFileUrlUniversalAccessTest
) {
2296 GURL url
= ui_test_utils::GetTestUrl(
2298 base::FilePath().AppendASCII("fileurl_universalaccess.html"));
2300 base::string16
expected_title(ASCIIToUTF16("Disallowed"));
2301 content::TitleWatcher
title_watcher(
2302 browser()->tab_strip_model()->GetActiveWebContents(), expected_title
);
2303 title_watcher
.AlsoWaitForTitle(ASCIIToUTF16("Allowed"));
2304 ui_test_utils::NavigateToURL(browser(), url
);
2305 ASSERT_EQ(expected_title
, title_watcher
.WaitAndGetTitle());
2308 class KioskModeTest
: public BrowserTest
{
2312 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2313 command_line
->AppendSwitch(switches::kKioskMode
);
2317 #if defined(OS_MACOSX) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
2318 // Mac: http://crbug.com/103912
2319 // Linux: http://crbug.com/163931
2320 #define MAYBE_EnableKioskModeTest DISABLED_EnableKioskModeTest
2322 #define MAYBE_EnableKioskModeTest EnableKioskModeTest
2324 IN_PROC_BROWSER_TEST_F(KioskModeTest
, MAYBE_EnableKioskModeTest
) {
2325 // Check if browser is in fullscreen mode.
2326 ASSERT_TRUE(browser()->window()->IsFullscreen());
2327 ASSERT_FALSE(browser()->window()->IsFullscreenBubbleVisible());
2331 // This test verifies that Chrome can be launched with a user-data-dir path
2332 // which contains non ASCII characters.
2333 class LaunchBrowserWithNonAsciiUserDatadir
: public BrowserTest
{
2335 LaunchBrowserWithNonAsciiUserDatadir() {}
2337 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2338 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
2339 base::FilePath tmp_profile
= temp_dir_
.path().AppendASCII("tmp_profile");
2340 tmp_profile
= tmp_profile
.Append(L
"Test Chrome G\u00E9raldine");
2342 ASSERT_TRUE(base::CreateDirectory(tmp_profile
));
2343 command_line
->AppendSwitchPath(switches::kUserDataDir
, tmp_profile
);
2346 base::ScopedTempDir temp_dir_
;
2349 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithNonAsciiUserDatadir
,
2350 TestNonAsciiUserDataDir
) {
2351 // Verify that the window is present.
2352 ASSERT_TRUE(browser());
2353 ASSERT_TRUE(browser()->profile());
2354 // Verify that the profile has been added correctly to the ProfileInfoCache.
2355 ASSERT_EQ(1u, g_browser_process
->profile_manager()->
2356 GetProfileInfoCache().GetNumberOfProfiles());
2358 #endif // defined(OS_WIN)
2361 // This test verifies that Chrome can be launched with a user-data-dir path
2362 // which trailing slashes.
2363 class LaunchBrowserWithTrailingSlashDatadir
: public BrowserTest
{
2365 LaunchBrowserWithTrailingSlashDatadir() {}
2367 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2368 ASSERT_TRUE(temp_dir_
.CreateUniqueTempDir());
2369 base::FilePath tmp_profile
= temp_dir_
.path().AppendASCII("tmp_profile");
2370 tmp_profile
= tmp_profile
.Append(L
"Test Chrome\\");
2372 ASSERT_TRUE(base::CreateDirectory(tmp_profile
));
2373 command_line
->AppendSwitchPath(switches::kUserDataDir
, tmp_profile
);
2376 base::ScopedTempDir temp_dir_
;
2379 IN_PROC_BROWSER_TEST_F(LaunchBrowserWithTrailingSlashDatadir
,
2380 TestTrailingSlashUserDataDir
) {
2381 // Verify that the window is present.
2382 ASSERT_TRUE(browser());
2383 ASSERT_TRUE(browser()->profile());
2384 // Verify that the profile has been added correctly to the ProfileInfoCache.
2385 ASSERT_EQ(1u, g_browser_process
->profile_manager()->
2386 GetProfileInfoCache().GetNumberOfProfiles());
2388 #endif // defined(OS_WIN)
2390 // Tests to ensure that the browser continues running in the background after
2391 // the last window closes.
2392 class RunInBackgroundTest
: public BrowserTest
{
2394 RunInBackgroundTest() {}
2396 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2397 command_line
->AppendSwitch(switches::kKeepAliveForTest
);
2401 IN_PROC_BROWSER_TEST_F(RunInBackgroundTest
, RunInBackgroundBasicTest
) {
2402 // Close the browser window, then open a new one - the browser should keep
2404 Profile
* profile
= browser()->profile();
2405 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2406 content::WindowedNotificationObserver
observer(
2407 chrome::NOTIFICATION_BROWSER_CLOSED
,
2408 content::Source
<Browser
>(browser()));
2409 chrome::CloseWindow(browser());
2411 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2413 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2414 chrome::NewEmptyWindow(profile
, chrome::GetActiveDesktop());
2415 browser_added_observer
.WaitForSingleNewBrowser();
2417 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2420 // Tests to ensure that the browser continues running in the background after
2421 // the last window closes.
2422 class NoStartupWindowTest
: public BrowserTest
{
2424 NoStartupWindowTest() {}
2426 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2427 command_line
->AppendSwitch(switches::kNoStartupWindow
);
2428 command_line
->AppendSwitch(switches::kKeepAliveForTest
);
2431 // Returns true if any commands were processed.
2432 bool ProcessedAnyCommands(
2433 sessions::BaseSessionService
* base_session_service
) {
2434 sessions::BaseSessionServiceTestHelper
test_helper(base_session_service
);
2435 return test_helper
.ProcessedAnyCommands();
2439 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest
, NoStartupWindowBasicTest
) {
2440 #if defined(OS_WIN) && defined(USE_ASH)
2441 // kNoStartupWindow doesn't make sense in Metro+Ash.
2442 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2443 switches::kAshBrowserTests
))
2447 // No browser window should be started by default.
2448 EXPECT_EQ(0u, chrome::GetTotalBrowserCount());
2450 // Starting a browser window should work just fine.
2451 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2452 CreateBrowser(ProfileManager::GetActiveUserProfile());
2453 browser_added_observer
.WaitForSingleNewBrowser();
2455 EXPECT_EQ(1u, chrome::GetTotalBrowserCount());
2458 // Chromeos needs to track app windows because it considers them to be part of
2460 #if !defined(OS_CHROMEOS)
2461 IN_PROC_BROWSER_TEST_F(NoStartupWindowTest
, DontInitSessionServiceForApps
) {
2462 #if defined(OS_WIN) && defined(USE_ASH)
2463 // kNoStartupWindow doesn't make sense in Metro+Ash.
2464 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2465 switches::kAshBrowserTests
))
2469 Profile
* profile
= ProfileManager::GetActiveUserProfile();
2471 SessionService
* session_service
=
2472 SessionServiceFactory::GetForProfile(profile
);
2473 sessions::BaseSessionService
* base_session_service
=
2474 session_service
->GetBaseSessionServiceForTest();
2475 ASSERT_FALSE(ProcessedAnyCommands(base_session_service
));
2477 ui_test_utils::BrowserAddedObserver browser_added_observer
;
2478 CreateBrowserForApp("blah", profile
);
2479 browser_added_observer
.WaitForSingleNewBrowser();
2481 ASSERT_FALSE(ProcessedAnyCommands(base_session_service
));
2483 #endif // !defined(OS_CHROMEOS)
2485 // This test needs to be placed outside the anonymous namespace because we
2486 // need to access private type of Browser.
2487 class AppModeTest
: public BrowserTest
{
2491 void SetUpCommandLine(base::CommandLine
* command_line
) override
{
2492 GURL url
= ui_test_utils::GetTestUrl(
2493 base::FilePath(), base::FilePath().AppendASCII("title1.html"));
2494 command_line
->AppendSwitchASCII(switches::kApp
, url
.spec());
2498 IN_PROC_BROWSER_TEST_F(AppModeTest
, EnableAppModeTest
) {
2499 #if defined(OS_WIN) && defined(USE_ASH)
2500 // Disable this test in Metro+Ash for now (http://crbug.com/262796).
2501 if (base::CommandLine::ForCurrentProcess()->HasSwitch(
2502 switches::kAshBrowserTests
))
2506 // Test that an application browser window loads correctly.
2508 // Verify the browser is in application mode.
2509 EXPECT_TRUE(browser()->is_app());
2512 // Confirm chrome://version contains some expected content.
2513 IN_PROC_BROWSER_TEST_F(BrowserTest
, AboutVersion
) {
2514 ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUIVersionURL
));
2515 WebContents
* tab
= browser()->tab_strip_model()->GetActiveWebContents();
2516 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("WebKit"), true, true,
2519 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("OS"), true, true,
2522 ASSERT_GT(ui_test_utils::FindInPage(tab
, ASCIIToUTF16("JavaScript"), true,
2527 static const base::FilePath::CharType
* kTestDir
=
2528 FILE_PATH_LITERAL("click_modifier");
2529 static const char kFirstPageTitle
[] = "First window";
2530 static const char kSecondPageTitle
[] = "New window!";
2532 class ClickModifierTest
: public InProcessBrowserTest
{
2534 ClickModifierTest() {
2537 // Returns a url that opens a new window or tab when clicked, via javascript.
2538 GURL
GetWindowOpenURL() {
2539 return ui_test_utils::GetTestUrl(
2540 base::FilePath(kTestDir
),
2541 base::FilePath(FILE_PATH_LITERAL("window_open.html")));
2544 // Returns a url that follows a simple link when clicked, unless affected by
2547 return ui_test_utils::GetTestUrl(
2548 base::FilePath(kTestDir
),
2549 base::FilePath(FILE_PATH_LITERAL("href.html")));
2552 base::string16
getFirstPageTitle() {
2553 return ASCIIToUTF16(kFirstPageTitle
);
2556 base::string16
getSecondPageTitle() {
2557 return ASCIIToUTF16(kSecondPageTitle
);
2560 // Loads our test page and simulates a single click using the supplied button
2561 // and modifiers. The click will cause either a navigation or the creation of
2562 // a new window or foreground or background tab. We verify that the expected
2563 // disposition occurs.
2564 void RunTest(Browser
* browser
,
2567 blink::WebMouseEvent::Button button
,
2568 WindowOpenDisposition disposition
) {
2569 ui_test_utils::NavigateToURL(browser
, url
);
2570 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2571 browser
->host_desktop_type()));
2572 EXPECT_EQ(1, browser
->tab_strip_model()->count());
2573 content::WebContents
* web_contents
=
2574 browser
->tab_strip_model()->GetActiveWebContents();
2575 EXPECT_EQ(url
, web_contents
->GetURL());
2577 if (disposition
== CURRENT_TAB
) {
2578 content::WebContents
* web_contents
=
2579 browser
->tab_strip_model()->GetActiveWebContents();
2580 content::TestNavigationObserver
same_tab_observer(web_contents
);
2581 SimulateMouseClick(web_contents
, modifiers
, button
);
2582 same_tab_observer
.Wait();
2583 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2584 browser
->host_desktop_type()));
2585 EXPECT_EQ(1, browser
->tab_strip_model()->count());
2586 EXPECT_EQ(getSecondPageTitle(), web_contents
->GetTitle());
2590 content::WindowedNotificationObserver
observer(
2591 chrome::NOTIFICATION_TAB_ADDED
,
2592 content::NotificationService::AllSources());
2593 SimulateMouseClick(web_contents
, modifiers
, button
);
2596 if (disposition
== NEW_WINDOW
) {
2597 EXPECT_EQ(2u, chrome::GetBrowserCount(browser
->profile(),
2598 browser
->host_desktop_type()));
2602 EXPECT_EQ(1u, chrome::GetBrowserCount(browser
->profile(),
2603 browser
->host_desktop_type()));
2604 EXPECT_EQ(2, browser
->tab_strip_model()->count());
2605 web_contents
= browser
->tab_strip_model()->GetActiveWebContents();
2606 WaitForLoadStop(web_contents
);
2607 if (disposition
== NEW_FOREGROUND_TAB
) {
2608 EXPECT_EQ(getSecondPageTitle(), web_contents
->GetTitle());
2610 ASSERT_EQ(NEW_BACKGROUND_TAB
, disposition
);
2611 EXPECT_EQ(getFirstPageTitle(), web_contents
->GetTitle());
2616 DISALLOW_COPY_AND_ASSIGN(ClickModifierTest
);
2619 // Tests for clicking on elements with handlers that run window.open.
2621 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenBasicClickTest
) {
2623 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2624 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2625 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2628 // TODO(ericu): Alt-click behavior on window.open is platform-dependent and not
2629 // well defined. Should we add tests so we know if it changes?
2631 // Shift-clicks open in a new window.
2632 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenShiftClickTest
) {
2633 int modifiers
= blink::WebInputEvent::ShiftKey
;
2634 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2635 WindowOpenDisposition disposition
= NEW_WINDOW
;
2636 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2639 // Control-clicks open in a background tab.
2640 // On OSX meta [the command key] takes the place of control.
2641 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenControlClickTest
) {
2642 #if defined(OS_MACOSX)
2643 int modifiers
= blink::WebInputEvent::MetaKey
;
2645 int modifiers
= blink::WebInputEvent::ControlKey
;
2647 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2648 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2649 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2652 // Control-shift-clicks open in a foreground tab.
2653 // On OSX meta [the command key] takes the place of control.
2654 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenControlShiftClickTest
) {
2655 #if defined(OS_MACOSX)
2656 int modifiers
= blink::WebInputEvent::MetaKey
;
2658 int modifiers
= blink::WebInputEvent::ControlKey
;
2660 modifiers
|= blink::WebInputEvent::ShiftKey
;
2661 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2662 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2663 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2666 // Middle-clicks open in a background tab.
2667 #if defined(OS_LINUX)
2668 // http://crbug.com/396347
2669 #define MAYBE_WindowOpenMiddleClickTest DISABLED_WindowOpenMiddleClickTest
2671 #define MAYBE_WindowOpenMiddleClickTest WindowOpenMiddleClickTest
2673 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, MAYBE_WindowOpenMiddleClickTest
) {
2675 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2676 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2677 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2680 // Shift-middle-clicks open in a foreground tab.
2681 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, WindowOpenShiftMiddleClickTest
) {
2682 int modifiers
= blink::WebInputEvent::ShiftKey
;
2683 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2684 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2685 RunTest(browser(), GetWindowOpenURL(), modifiers
, button
, disposition
);
2688 // Tests for clicking on normal links.
2690 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefBasicClickTest
) {
2692 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2693 WindowOpenDisposition disposition
= CURRENT_TAB
;
2694 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2697 // TODO(ericu): Alt-click behavior on links is platform-dependent and not well
2698 // defined. Should we add tests so we know if it changes?
2700 // Shift-clicks open in a new window.
2701 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefShiftClickTest
) {
2702 int modifiers
= blink::WebInputEvent::ShiftKey
;
2703 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2704 WindowOpenDisposition disposition
= NEW_WINDOW
;
2705 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2708 // Control-clicks open in a background tab.
2709 // On OSX meta [the command key] takes the place of control.
2710 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefControlClickTest
) {
2711 #if defined(OS_MACOSX)
2712 int modifiers
= blink::WebInputEvent::MetaKey
;
2714 int modifiers
= blink::WebInputEvent::ControlKey
;
2716 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2717 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2718 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2721 // Control-shift-clicks open in a foreground tab.
2722 // On OSX meta [the command key] takes the place of control.
2723 // http://crbug.com/396347
2724 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, DISABLED_HrefControlShiftClickTest
) {
2725 #if defined(OS_MACOSX)
2726 int modifiers
= blink::WebInputEvent::MetaKey
;
2728 int modifiers
= blink::WebInputEvent::ControlKey
;
2730 modifiers
|= blink::WebInputEvent::ShiftKey
;
2731 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonLeft
;
2732 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2733 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2736 // Middle-clicks open in a background tab.
2737 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, HrefMiddleClickTest
) {
2739 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2740 WindowOpenDisposition disposition
= NEW_BACKGROUND_TAB
;
2741 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2744 // Shift-middle-clicks open in a foreground tab.
2745 // http://crbug.com/396347
2746 IN_PROC_BROWSER_TEST_F(ClickModifierTest
, DISABLED_HrefShiftMiddleClickTest
) {
2747 int modifiers
= blink::WebInputEvent::ShiftKey
;
2748 blink::WebMouseEvent::Button button
= blink::WebMouseEvent::ButtonMiddle
;
2749 WindowOpenDisposition disposition
= NEW_FOREGROUND_TAB
;
2750 RunTest(browser(), GetHrefURL(), modifiers
, button
, disposition
);
2753 IN_PROC_BROWSER_TEST_F(BrowserTest
, GetSizeForNewRenderView
) {
2754 #if defined(OS_MACOSX) && !defined(OS_IOS)
2755 // TODO(erikchen): This behavior has regressed on OSX 10.7 and 10.8 and should
2756 // be fixed. http://crbug.com/503185
2757 if (base::mac::IsOSMountainLion() || base::mac::IsOSLion())
2759 #endif // defined(OS_MACOSX) && !defined(OS_IOS)
2760 // The instant extended NTP has javascript that does not work with
2761 // ui_test_utils::NavigateToURL. The NTP rvh reloads when the browser tries
2762 // to navigate away from the page, which causes the WebContents to end up in
2763 // an inconsistent state. (is_loaded = true, last_commited_url=ntp,
2764 // visible_url=title1.html)
2765 browser()->profile()->GetPrefs()->SetBoolean(prefs::kWebKitJavascriptEnabled
,
2767 ASSERT_TRUE(test_server()->Start());
2768 // Create an HTTPS server for cross-site transition.
2769 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
2770 net::SpawnedTestServer::kLocalhost
,
2771 base::FilePath(kDocRoot
));
2772 ASSERT_TRUE(https_test_server
.Start());
2775 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2776 ASSERT_EQ(BookmarkBar::DETACHED
, browser()->bookmark_bar_state());
2777 WebContents
* web_contents
=
2778 browser()->tab_strip_model()->GetActiveWebContents();
2779 content::RenderViewHost
* prev_rvh
= web_contents
->GetRenderViewHost();
2780 const int height_inset
=
2781 browser()->window()->GetRenderViewHeightInsetWithDetachedBookmarkBar();
2782 const gfx::Size initial_wcv_size
=
2783 web_contents
->GetContainerBounds().size();
2784 RenderViewSizeObserver
observer(web_contents
, browser()->window());
2786 // Navigate to a non-NTP page, without resizing WebContentsView.
2787 ui_test_utils::NavigateToURL(browser(),
2788 test_server()->GetURL("files/title1.html"));
2789 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2790 // A new RenderViewHost should be created.
2791 EXPECT_NE(prev_rvh
, web_contents
->GetRenderViewHost());
2792 prev_rvh
= web_contents
->GetRenderViewHost();
2793 gfx::Size rwhv_create_size0
, rwhv_commit_size0
, wcv_commit_size0
;
2794 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2798 // The create height of RenderWidgetHostView should include the height inset.
2799 EXPECT_EQ(gfx::Size(initial_wcv_size
.width(),
2800 initial_wcv_size
.height() + height_inset
),
2802 // When a navigation entry is committed, the size of RenderWidgetHostView
2803 // should be the same as when it was first created.
2804 EXPECT_EQ(rwhv_create_size0
, rwhv_commit_size0
);
2805 // Sizes of the current RenderWidgetHostView and WebContentsView should not
2806 // change before and after WebContentsDelegate::DidNavigateMainFramePostCommit
2807 // (implemented by Browser); we obtain the sizes before PostCommit via
2808 // WebContentsObserver::NavigationEntryCommitted (implemented by
2809 // RenderViewSizeObserver).
2810 EXPECT_EQ(rwhv_commit_size0
,
2811 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2812 // The behavior differs between OSX and views.
2813 // In OSX, the wcv does not change size until after the commit, when the
2814 // bookmark bar disappears (correct).
2815 // In views, the wcv changes size at commit time.
2816 #if defined(OS_MACOSX)
2817 EXPECT_EQ(gfx::Size(wcv_commit_size0
.width(),
2818 wcv_commit_size0
.height() + height_inset
),
2819 web_contents
->GetContainerBounds().size());
2821 EXPECT_EQ(wcv_commit_size0
, web_contents
->GetContainerBounds().size());
2824 // Navigate to another non-NTP page, without resizing WebContentsView.
2825 ui_test_utils::NavigateToURL(browser(),
2826 https_test_server
.GetURL("files/title2.html"));
2827 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2828 // A new RenderVieHost should be created.
2829 EXPECT_NE(prev_rvh
, web_contents
->GetRenderViewHost());
2830 gfx::Size rwhv_create_size1
, rwhv_commit_size1
, wcv_commit_size1
;
2831 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2835 EXPECT_EQ(rwhv_create_size1
, rwhv_commit_size1
);
2836 EXPECT_EQ(rwhv_commit_size1
,
2837 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2838 EXPECT_EQ(wcv_commit_size1
, web_contents
->GetContainerBounds().size());
2840 // Navigate from NTP to a non-NTP page, resizing WebContentsView while
2841 // navigation entry is pending.
2842 ui_test_utils::NavigateToURL(browser(), GURL("chrome://newtab"));
2843 gfx::Size
wcv_resize_insets(1, 1);
2844 observer
.set_wcv_resize_insets(wcv_resize_insets
);
2845 ui_test_utils::NavigateToURL(browser(),
2846 test_server()->GetURL("files/title2.html"));
2847 ASSERT_EQ(BookmarkBar::HIDDEN
, browser()->bookmark_bar_state());
2848 gfx::Size rwhv_create_size2
, rwhv_commit_size2
, wcv_commit_size2
;
2849 observer
.GetSizeForRenderViewHost(web_contents
->GetRenderViewHost(),
2854 // The behavior on OSX and Views is incorrect in this edge case, but they are
2855 // differently incorrect.
2856 // The behavior should be:
2857 // initial wcv size: (100,100) (to choose random numbers)
2858 // initial rwhv size: (100,140)
2859 // commit wcv size: (101, 101)
2860 // commit rwhv size: (101, 141)
2861 // final wcv size: (101, 141)
2862 // final rwhv size: (101, 141)
2864 // On OSX, the commit rwhv size is (101, 101)
2865 // On views, the commit wcv size is (101, 141)
2866 // All other sizes are correct.
2868 // The create height of RenderWidgetHostView should include the height inset.
2869 EXPECT_EQ(gfx::Size(initial_wcv_size
.width(),
2870 initial_wcv_size
.height() + height_inset
),
2872 gfx::Size
exp_commit_size(initial_wcv_size
);
2874 #if defined(OS_MACOSX)
2875 exp_commit_size
.Enlarge(wcv_resize_insets
.width(),
2876 wcv_resize_insets
.height());
2878 exp_commit_size
.Enlarge(wcv_resize_insets
.width(),
2879 wcv_resize_insets
.height() + height_inset
);
2881 EXPECT_EQ(exp_commit_size
, rwhv_commit_size2
);
2882 EXPECT_EQ(exp_commit_size
, wcv_commit_size2
);
2883 gfx::Size
exp_final_size(initial_wcv_size
);
2884 exp_final_size
.Enlarge(wcv_resize_insets
.width(),
2885 wcv_resize_insets
.height() + height_inset
);
2886 EXPECT_EQ(exp_final_size
,
2887 web_contents
->GetRenderWidgetHostView()->GetViewBounds().size());
2888 EXPECT_EQ(exp_final_size
, web_contents
->GetContainerBounds().size());
2891 IN_PROC_BROWSER_TEST_F(BrowserTest
, CanDuplicateTab
) {
2892 GURL
url(ui_test_utils::GetTestUrl(
2893 base::FilePath(base::FilePath::kCurrentDirectory
),
2894 base::FilePath(kTitle1File
)));
2895 ui_test_utils::NavigateToURL(browser(), url
);
2897 AddTabAtIndex(0, url
, ui::PAGE_TRANSITION_TYPED
);
2899 int active_index
= browser()->tab_strip_model()->active_index();
2900 EXPECT_EQ(0, active_index
);
2902 EXPECT_TRUE(chrome::CanDuplicateTab(browser()));
2903 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0));
2904 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2906 content::WebContents
* web_contents
=
2907 browser()->tab_strip_model()->GetActiveWebContents();
2909 TestInterstitialPage
* interstitial
=
2910 new TestInterstitialPage(web_contents
, false, GURL());
2911 content::WaitForInterstitialAttach(web_contents
);
2913 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
2915 // Verify that the "Duplicate tab" command is disabled on interstitial
2916 // pages. Regression test for crbug.com/310812
2917 EXPECT_FALSE(chrome::CanDuplicateTab(browser()));
2918 EXPECT_FALSE(chrome::CanDuplicateTabAt(browser(), 0));
2919 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2921 // Don't proceed and wait for interstitial to detach. This doesn't
2922 // destroy |contents|.
2923 interstitial
->DontProceed();
2924 content::WaitForInterstitialDetach(web_contents
);
2925 // interstitial is deleted now.
2927 EXPECT_TRUE(chrome::CanDuplicateTab(browser()));
2928 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 0));
2929 EXPECT_TRUE(chrome::CanDuplicateTabAt(browser(), 1));
2932 // Tests that the WebContentsObserver::SecurityStyleChanged event fires
2933 // with the current style on HTTP, broken HTTPS, and valid HTTPS pages.
2934 IN_PROC_BROWSER_TEST_F(BrowserTest
, SecurityStyleChangedObserver
) {
2935 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
2936 net::SpawnedTestServer::kLocalhost
,
2937 base::FilePath(kDocRoot
));
2938 net::SpawnedTestServer
https_test_server_expired(
2939 net::SpawnedTestServer::TYPE_HTTPS
,
2940 net::SpawnedTestServer::SSLOptions(
2941 net::SpawnedTestServer::SSLOptions::CERT_EXPIRED
),
2942 base::FilePath(kDocRoot
));
2944 ASSERT_TRUE(https_test_server
.Start());
2945 ASSERT_TRUE(https_test_server_expired
.Start());
2946 ASSERT_TRUE(test_server()->Start());
2948 content::WebContents
* web_contents
=
2949 browser()->tab_strip_model()->GetActiveWebContents();
2950 SecurityStyleTestObserver
observer(web_contents
);
2952 // Visit an HTTP url.
2953 GURL
http_url(test_server()->GetURL(std::string()));
2954 ui_test_utils::NavigateToURL(browser(), http_url
);
2955 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED
,
2956 observer
.latest_security_style());
2957 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
2958 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
2959 EXPECT_EQ(0u, observer
.latest_explanations().secure_explanations
.size());
2960 EXPECT_FALSE(observer
.latest_explanations().scheme_is_cryptographic
);
2961 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
2962 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
2964 // Visit an (otherwise valid) HTTPS page that displays mixed content.
2965 std::string replacement_path
;
2966 ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
2967 "files/ssl/page_displays_insecure_content.html",
2968 test_server()->host_port_pair(), &replacement_path
));
2970 GURL
mixed_content_url(https_test_server
.GetURL(replacement_path
));
2971 ui_test_utils::NavigateToURL(browser(), mixed_content_url
);
2972 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED
,
2973 observer
.latest_security_style());
2975 const content::SecurityStyleExplanations
& mixed_content_explanation
=
2976 observer
.latest_explanations();
2977 ASSERT_EQ(0u, mixed_content_explanation
.warning_explanations
.size());
2978 ASSERT_EQ(0u, mixed_content_explanation
.broken_explanations
.size());
2979 CheckSecureExplanations(mixed_content_explanation
.secure_explanations
,
2981 EXPECT_TRUE(mixed_content_explanation
.scheme_is_cryptographic
);
2982 EXPECT_TRUE(mixed_content_explanation
.displayed_insecure_content
);
2983 EXPECT_FALSE(mixed_content_explanation
.ran_insecure_content
);
2984 EXPECT_EQ(content::SECURITY_STYLE_UNAUTHENTICATED
,
2985 mixed_content_explanation
.displayed_insecure_content_style
);
2986 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATION_BROKEN
,
2987 mixed_content_explanation
.ran_insecure_content_style
);
2989 // Visit a broken HTTPS url.
2990 GURL
expired_url(https_test_server_expired
.GetURL(std::string()));
2991 ui_test_utils::NavigateToURL(browser(), expired_url
);
2993 // An interstitial should show, and an event for the lock icon on the
2994 // interstitial should fire.
2995 content::WaitForInterstitialAttach(web_contents
);
2996 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
2997 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_DATE_INVALID
);
2998 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
2999 INVALID_CERTIFICATE
);
3000 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3001 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3002 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3004 // Before clicking through, navigate to a different page, and then go
3005 // back to the interstitial.
3006 GURL
valid_https_url(https_test_server
.GetURL(std::string()));
3007 ui_test_utils::NavigateToURL(browser(), valid_https_url
);
3008 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED
,
3009 observer
.latest_security_style());
3010 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
3011 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
3012 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3014 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3015 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3016 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3018 // After going back to the interstitial, an event for a broken lock
3019 // icon should fire again.
3020 ui_test_utils::NavigateToURL(browser(), expired_url
);
3021 content::WaitForInterstitialAttach(web_contents
);
3022 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
3023 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_DATE_INVALID
);
3024 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3025 INVALID_CERTIFICATE
);
3026 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3027 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3028 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3030 // Since the next expected style is the same as the previous, clear
3031 // the observer (to make sure that the event fires twice and we don't
3032 // just see the previous event's style).
3033 observer
.ClearLatestSecurityStyleAndExplanations();
3035 // Other conditions cannot be tested on this host after clicking
3036 // through because once the interstitial is clicked through, all URLs
3037 // for this host will remain in a broken state.
3038 ProceedThroughInterstitial(web_contents
);
3039 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_DATE_INVALID
);
3040 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3041 INVALID_CERTIFICATE
);
3042 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3043 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3044 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3047 // Visit a valid HTTPS page, then a broken HTTPS page, and then go back,
3048 // and test that the observed security style matches.
3049 IN_PROC_BROWSER_TEST_F(BrowserTest
, SecurityStyleChangedObserverGoBack
) {
3050 net::SpawnedTestServer
https_test_server(net::SpawnedTestServer::TYPE_HTTPS
,
3051 net::SpawnedTestServer::kLocalhost
,
3052 base::FilePath(kDocRoot
));
3054 // Use a separate server to work around a mysterious SSL handshake
3055 // timeout when both requests go to the same server. See
3056 // https://crbug.com/515906.
3057 net::SpawnedTestServer
https_test_server_expired(
3058 net::SpawnedTestServer::TYPE_HTTPS
,
3059 net::SpawnedTestServer::SSLOptions(
3060 net::SpawnedTestServer::SSLOptions::CERT_EXPIRED
),
3061 base::FilePath(kDocRoot
));
3063 ASSERT_TRUE(https_test_server
.Start());
3064 ASSERT_TRUE(https_test_server_expired
.Start());
3066 content::WebContents
* web_contents
=
3067 browser()->tab_strip_model()->GetActiveWebContents();
3068 SecurityStyleTestObserver
observer(web_contents
);
3070 // Visit a valid HTTPS url.
3071 GURL
valid_https_url(https_test_server
.GetURL(std::string()));
3072 ui_test_utils::NavigateToURL(browser(), valid_https_url
);
3073 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED
,
3074 observer
.latest_security_style());
3075 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
3076 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
3077 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3079 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3080 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3081 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3083 // Navigate to a bad HTTPS page on a different host, and then click
3084 // Back to verify that the previous good security style is seen again.
3085 GURL
expired_https_url(https_test_server_expired
.GetURL(std::string()));
3086 host_resolver()->AddRule("www.example_broken.test", "127.0.0.1");
3087 GURL::Replacements replace_host
;
3088 replace_host
.SetHostStr("www.example_broken.test");
3089 GURL https_url_different_host
=
3090 expired_https_url
.ReplaceComponents(replace_host
);
3092 ui_test_utils::NavigateToURL(browser(), https_url_different_host
);
3094 content::WaitForInterstitialAttach(web_contents
);
3095 EXPECT_TRUE(web_contents
->ShowingInterstitialPage());
3096 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_COMMON_NAME_INVALID
);
3097 ProceedThroughInterstitial(web_contents
);
3098 CheckBrokenSecurityStyle(observer
, net::ERR_CERT_COMMON_NAME_INVALID
);
3099 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3100 INVALID_CERTIFICATE
);
3101 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3102 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3103 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);
3105 content::WindowedNotificationObserver
back_nav_load_observer(
3106 content::NOTIFICATION_LOAD_STOP
,
3107 content::Source
<NavigationController
>(&web_contents
->GetController()));
3108 chrome::GoBack(browser(), CURRENT_TAB
);
3109 back_nav_load_observer
.Wait();
3111 EXPECT_EQ(content::SECURITY_STYLE_AUTHENTICATED
,
3112 observer
.latest_security_style());
3113 EXPECT_EQ(0u, observer
.latest_explanations().warning_explanations
.size());
3114 EXPECT_EQ(0u, observer
.latest_explanations().broken_explanations
.size());
3115 CheckSecureExplanations(observer
.latest_explanations().secure_explanations
,
3117 EXPECT_TRUE(observer
.latest_explanations().scheme_is_cryptographic
);
3118 EXPECT_FALSE(observer
.latest_explanations().displayed_insecure_content
);
3119 EXPECT_FALSE(observer
.latest_explanations().ran_insecure_content
);