1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/basictypes.h"
10 #include "base/command_line.h"
11 #include "base/compiler_specific.h"
12 #include "base/files/file_path.h"
13 #include "base/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/utf_string_conversions.h"
17 #include "chrome/browser/captive_portal/captive_portal_service.h"
18 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
19 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
20 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
21 #include "chrome/browser/net/url_request_mock_util.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_commands.h"
25 #include "chrome/browser/ui/browser_finder.h"
26 #include "chrome/browser/ui/browser_navigator.h"
27 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
28 #include "chrome/browser/ui/tabs/tab_strip_model.h"
29 #include "chrome/common/chrome_notification_types.h"
30 #include "chrome/common/chrome_paths.h"
31 #include "chrome/common/chrome_switches.h"
32 #include "chrome/common/pref_names.h"
33 #include "chrome/test/base/in_process_browser_test.h"
34 #include "chrome/test/base/ui_test_utils.h"
35 #include "content/public/browser/browser_thread.h"
36 #include "content/public/browser/navigation_controller.h"
37 #include "content/public/browser/notification_observer.h"
38 #include "content/public/browser/notification_registrar.h"
39 #include "content/public/browser/notification_service.h"
40 #include "content/public/browser/notification_types.h"
41 #include "content/public/browser/render_view_host.h"
42 #include "content/public/browser/web_contents.h"
43 #include "content/public/common/url_constants.h"
44 #include "content/test/net/url_request_failed_job.h"
45 #include "content/test/net/url_request_mock_http_job.h"
46 #include "net/base/net_errors.h"
47 #include "net/http/transport_security_state.h"
48 #include "net/url_request/url_request.h"
49 #include "net/url_request/url_request_context.h"
50 #include "net/url_request/url_request_context_getter.h"
51 #include "net/url_request/url_request_filter.h"
52 #include "net/url_request/url_request_job.h"
53 #include "net/url_request/url_request_status.h"
54 #include "testing/gtest/include/gtest/gtest.h"
56 using content::BrowserThread
;
57 using content::URLRequestFailedJob
;
58 using content::URLRequestMockHTTPJob
;
59 using content::WebContents
;
61 namespace captive_portal
{
65 // Path of the fake login page, when using the TestServer.
66 const char* const kTestServerLoginPath
= "files/captive_portal/login.html";
68 // Path of a page with an iframe that has a mock SSL timeout, when using the
70 const char* const kTestServerIframeTimeoutPath
=
71 "files/captive_portal/iframe_timeout.html";
73 // The following URLs each have two different behaviors, depending on whether
74 // URLRequestMockCaptivePortalJobFactory is currently simulating the presence
75 // of a captive portal or not. They use different domains so that HSTS can be
76 // applied to them independently.
78 // A mock URL for the CaptivePortalService's |test_url|. When behind a captive
79 // portal, this URL returns a mock login page. When connected to the Internet,
80 // it returns a 204 response. Uses the name of the login file so that reloading
81 // it will not request a different URL.
82 const char* const kMockCaptivePortalTestUrl
=
83 "http://mock.captive.portal.test/login.html";
85 // Another mock URL for the CaptivePortalService's |test_url|. When behind a
86 // captive portal, this URL returns a 511 status code and an HTML page that
87 // redirect to the above URL. When connected to the Internet, it returns a 204
89 const char* const kMockCaptivePortal511Url
=
90 "http://mock.captive.portal.511/page511.html";
92 // When behind a captive portal, this URL hangs without committing until a call
93 // to URLRequestTimeoutOnDemandJob::FailJobs. When that function is called,
94 // the request will time out.
96 // When connected to the Internet, this URL returns a non-error page.
97 const char* const kMockHttpsUrl
=
98 "https://mock.captive.portal.long.timeout/title2.html";
100 // Same as above, but different domain, so can be used to trigger cross-site
102 const char* const kMockHttpsUrl2
=
103 "https://mock.captive.portal.long.timeout2/title2.html";
105 // Same as kMockHttpsUrl, except the timeout happens instantly.
106 const char* const kMockHttpsQuickTimeoutUrl
=
107 "https://mock.captive.portal.quick.timeout/title2.html";
109 // Expected title of a tab once an HTTPS load completes, when not behind a
111 const char* const kInternetConnectedTitle
= "Title Of Awesomeness";
113 // A URL request job that hangs until FailJobs() is called. Started jobs
114 // are stored in a static class variable containing a linked list so that
115 // FailJobs() can locate them.
116 class URLRequestTimeoutOnDemandJob
: public net::URLRequestJob
,
117 public base::NonThreadSafe
{
119 // net::URLRequestJob:
120 virtual void Start() OVERRIDE
;
122 // All the public static methods below can be called on any thread.
124 // Waits for exactly |num_jobs|.
125 static void WaitForJobs(int num_jobs
);
127 // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts.
128 // There are expected to be exactly |expected_num_jobs| waiting for
129 // failure. The only way to gaurantee this is with an earlier call to
130 // WaitForJobs, so makes sure there has been a matching WaitForJobs call.
131 static void FailJobs(int expected_num_jobs
);
133 // Abandon all active URLRequestTimeoutOnDemandJobs. |expected_num_jobs|
134 // behaves just as in FailJobs.
135 static void AbandonJobs(int expected_num_jobs
);
138 friend class URLRequestMockCaptivePortalJobFactory
;
140 // Operation to perform on jobs when removing them from |job_list_|.
141 enum EndJobOperation
{
146 URLRequestTimeoutOnDemandJob(net::URLRequest
* request
,
147 net::NetworkDelegate
* network_delegate
);
148 virtual ~URLRequestTimeoutOnDemandJob();
150 // Attempts to removes |this| from |jobs_|. Returns true if it was removed
152 bool RemoveFromList();
154 static void WaitForJobsOnIOThread(int num_jobs
);
155 static void FailOrAbandonJobsOnIOThread(
156 int expected_num_jobs
,
157 EndJobOperation end_job_operation
);
159 // Checks if there are at least |num_jobs_to_wait_for_| jobs in
160 // |job_list_|. If so, exits the message loop on the UI thread, which
161 // should be spinning in a call to WaitForJobs. Does nothing when
162 // |num_jobs_to_wait_for_| is 0.
163 static void MaybeStopWaitingForJobsOnIOThread();
165 // All class variables are only accessed on the IO thread.
167 // Number of jobs currently being waited for, or 0 if not currently
169 static int num_jobs_to_wait_for_
;
171 // The last number of jobs that were waited for. When FailJobs or
172 // AbandonJobs is called, this should match |expected_num_jobs|.
173 static int last_num_jobs_to_wait_for_
;
175 // Number of jobs that have been started, but not yet waited for. If jobs
176 // are deleted unexpectedly, they're still included in this count, even though
177 // they've been removed from |job_list_|. Intended to reduce chance of stalls
179 static int num_jobs_started_
;
181 // Head of linked list of jobs that have been started and are now waiting to
183 static URLRequestTimeoutOnDemandJob
* job_list_
;
185 // The next job that had been started but not yet timed out.
186 URLRequestTimeoutOnDemandJob
* next_job_
;
188 DISALLOW_COPY_AND_ASSIGN(URLRequestTimeoutOnDemandJob
);
191 int URLRequestTimeoutOnDemandJob::num_jobs_to_wait_for_
= 0;
192 int URLRequestTimeoutOnDemandJob::last_num_jobs_to_wait_for_
= 0;
193 int URLRequestTimeoutOnDemandJob::num_jobs_started_
= 0;
194 URLRequestTimeoutOnDemandJob
* URLRequestTimeoutOnDemandJob::job_list_
= NULL
;
196 void URLRequestTimeoutOnDemandJob::Start() {
197 EXPECT_TRUE(CalledOnValidThread());
199 // Insert at start of the list.
200 next_job_
= job_list_
;
204 // Checks if there are at least |num_jobs_to_wait_for_| jobs in
205 // |job_list_|. If so, exits the message loop on the UI thread, which
206 // should be spinning in a call to WaitForJobs. Does nothing if
207 // |num_jobs_to_wait_for_| is 0.
208 MaybeStopWaitingForJobsOnIOThread();
212 void URLRequestTimeoutOnDemandJob::WaitForJobs(int num_jobs
) {
213 content::BrowserThread::PostTask(
214 content::BrowserThread::IO
, FROM_HERE
,
215 base::Bind(&URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread
,
217 content::RunMessageLoop();
221 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs
) {
222 content::BrowserThread::PostTask(
223 content::BrowserThread::IO
, FROM_HERE
,
224 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread
,
230 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs
) {
231 content::BrowserThread::PostTask(
232 content::BrowserThread::IO
, FROM_HERE
,
233 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread
,
238 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
239 net::URLRequest
* request
, net::NetworkDelegate
* network_delegate
)
240 : net::URLRequestJob(request
, network_delegate
),
244 URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() {
245 // All hanging jobs should have failed or been abandoned before being
247 EXPECT_FALSE(RemoveFromList());
250 bool URLRequestTimeoutOnDemandJob::RemoveFromList() {
251 URLRequestTimeoutOnDemandJob
** job
= &job_list_
;
261 // If the job wasn't in this list, |next_job_| should be NULL.
262 EXPECT_FALSE(next_job_
);
267 void URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread(int num_jobs
) {
268 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
269 ASSERT_EQ(0, num_jobs_to_wait_for_
);
270 ASSERT_LT(0, num_jobs
);
271 // Number of tabs being waited on should be strictly increasing.
272 ASSERT_LE(last_num_jobs_to_wait_for_
, num_jobs
);
274 num_jobs_to_wait_for_
= num_jobs
;
275 MaybeStopWaitingForJobsOnIOThread();
279 void URLRequestTimeoutOnDemandJob::MaybeStopWaitingForJobsOnIOThread() {
280 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
281 if (num_jobs_to_wait_for_
== 0)
284 // There shouldn't be any extra jobs.
285 EXPECT_LE(num_jobs_started_
, num_jobs_to_wait_for_
);
287 // Should never be greater, but if it is, go ahead and exit the message loop
288 // to try and avoid hanging.
289 if (num_jobs_started_
>= num_jobs_to_wait_for_
) {
290 last_num_jobs_to_wait_for_
= num_jobs_to_wait_for_
;
291 num_jobs_to_wait_for_
= 0;
292 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
293 MessageLoop::QuitClosure());
298 void URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread(
299 int expected_num_jobs
,
300 EndJobOperation end_job_operation
) {
301 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
302 ASSERT_LT(0, expected_num_jobs
);
303 EXPECT_EQ(last_num_jobs_to_wait_for_
, expected_num_jobs
);
304 last_num_jobs_to_wait_for_
= 0;
309 URLRequestTimeoutOnDemandJob
* job
= job_list_
;
310 // Since the error notification may result in the job's destruction, remove
311 // it from the job list before the error.
312 EXPECT_TRUE(job
->RemoveFromList());
313 if (end_job_operation
== FAIL_JOBS
) {
314 job
->NotifyStartError(net::URLRequestStatus(
315 net::URLRequestStatus::FAILED
,
316 net::ERR_CONNECTION_TIMED_OUT
));
320 EXPECT_EQ(expected_num_jobs
, num_jobs_started_
);
321 EXPECT_EQ(expected_num_jobs
, num_jobs
);
323 num_jobs_started_
-= expected_num_jobs
;
326 // URLRequestCaptivePortalJobFactory emulates captive portal behavior.
327 // Initially, it emulates being behind a captive portal. When
328 // SetBehindCaptivePortal(false) is called, it emulates behavior when not behind
329 // a captive portal. The class itself is never instantiated.
331 // It handles requests for kMockCaptivePortalTestUrl, kMockHttpsUrl, and
332 // kMockHttpsQuickTimeoutUrl.
333 class URLRequestMockCaptivePortalJobFactory
{
335 // The public static methods below can be called on any thread.
337 // Adds the testing URLs to the net::URLRequestFilter. Should only be called
339 static void AddUrlHandlers();
341 // Sets whether or not there is a captive portal. Outstanding requests are
343 static void SetBehindCaptivePortal(bool behind_captive_portal
);
346 // These do all the work of the corresponding public functions, with the only
347 // difference being that they must be called on the IO thread.
348 static void AddUrlHandlersOnIOThread();
349 static void SetBehindCaptivePortalOnIOThread(bool behind_captive_portal
);
351 // Returns a URLRequestJob that reflects the current captive portal state
352 // for the URLs: kMockCaptivePortalTestUrl, kMockHttpsUrl, and
353 // kMockHttpsQuickTimeoutUrl. See documentation of individual URLs for
355 static net::URLRequestJob
* Factory(net::URLRequest
* request
,
356 net::NetworkDelegate
* network_delegate
,
357 const std::string
& scheme
);
359 static bool behind_captive_portal_
;
361 DISALLOW_IMPLICIT_CONSTRUCTORS(URLRequestMockCaptivePortalJobFactory
);
364 bool URLRequestMockCaptivePortalJobFactory::behind_captive_portal_
= true;
367 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() {
368 content::BrowserThread::PostTask(
369 content::BrowserThread::IO
, FROM_HERE
,
371 &URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread
));
375 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(
376 bool behind_captive_portal
) {
377 content::BrowserThread::PostTask(
378 content::BrowserThread::IO
, FROM_HERE
,
380 &URLRequestMockCaptivePortalJobFactory::
381 SetBehindCaptivePortalOnIOThread
,
382 behind_captive_portal
));
386 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() {
387 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
389 // Handle only exact matches, so any related requests, such as those for
390 // favicons, are not handled by the factory.
391 net::URLRequestFilter
* filter
= net::URLRequestFilter::GetInstance();
392 filter
->AddUrlHandler(GURL(kMockCaptivePortalTestUrl
),
393 URLRequestMockCaptivePortalJobFactory::Factory
);
394 filter
->AddUrlHandler(GURL(kMockCaptivePortal511Url
),
395 URLRequestMockCaptivePortalJobFactory::Factory
);
396 filter
->AddUrlHandler(GURL(kMockHttpsUrl
),
397 URLRequestMockCaptivePortalJobFactory::Factory
);
398 filter
->AddUrlHandler(GURL(kMockHttpsUrl2
),
399 URLRequestMockCaptivePortalJobFactory::Factory
);
400 filter
->AddUrlHandler(GURL(kMockHttpsQuickTimeoutUrl
),
401 URLRequestMockCaptivePortalJobFactory::Factory
);
405 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread(
406 bool behind_captive_portal
) {
407 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
408 behind_captive_portal_
= behind_captive_portal
;
412 net::URLRequestJob
* URLRequestMockCaptivePortalJobFactory::Factory(
413 net::URLRequest
* request
,
414 net::NetworkDelegate
* network_delegate
,
415 const std::string
& scheme
) {
416 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
418 // The PathService is threadsafe.
419 base::FilePath root_http
;
420 PathService::Get(chrome::DIR_TEST_DATA
, &root_http
);
422 if (request
->url() == GURL(kMockHttpsUrl
) ||
423 request
->url() == GURL(kMockHttpsUrl2
)) {
424 if (behind_captive_portal_
)
425 return new URLRequestTimeoutOnDemandJob(request
, network_delegate
);
426 // Once logged in to the portal, HTTPS requests return the page that was
427 // actually requested.
428 return new URLRequestMockHTTPJob(
431 root_http
.Append(FILE_PATH_LITERAL("title2.html")));
432 } else if (request
->url() == GURL(kMockHttpsQuickTimeoutUrl
)) {
433 if (behind_captive_portal_
)
434 return new URLRequestFailedJob(
435 request
, network_delegate
, net::ERR_CONNECTION_TIMED_OUT
);
436 // Once logged in to the portal, HTTPS requests return the page that was
437 // actually requested.
438 return new URLRequestMockHTTPJob(
441 root_http
.Append(FILE_PATH_LITERAL("title2.html")));
443 // The URL should be the captive portal test URL.
444 EXPECT_TRUE(GURL(kMockCaptivePortalTestUrl
) == request
->url() ||
445 GURL(kMockCaptivePortal511Url
) == request
->url());
447 if (behind_captive_portal_
) {
448 // Prior to logging in to the portal, the HTTP test URLs are intercepted
449 // by the captive portal.
450 if (GURL(kMockCaptivePortal511Url
) == request
->url()) {
451 return new URLRequestMockHTTPJob(
454 root_http
.Append(FILE_PATH_LITERAL("captive_portal/page511.html")));
456 return new URLRequestMockHTTPJob(
459 root_http
.Append(FILE_PATH_LITERAL("captive_portal/login.html")));
462 // After logging in to the portal, the test URLs return a 204 response.
463 return new URLRequestMockHTTPJob(
466 root_http
.Append(FILE_PATH_LITERAL("captive_portal/page204.html")));
470 // Creates a server-side redirect for use with the TestServer.
471 std::string
CreateServerRedirect(const std::string
& dest_url
) {
472 const char* const kServerRedirectBase
= "server-redirect?";
473 return kServerRedirectBase
+ dest_url
;
476 // Returns the total number of loading tabs across all Browsers, for all
478 int NumLoadingTabs() {
479 int num_loading_tabs
= 0;
480 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
484 return num_loading_tabs
;
487 bool IsLoginTab(WebContents
* web_contents
) {
488 return CaptivePortalTabHelper::FromWebContents(web_contents
)->IsLoginTab();
491 // Tracks how many times each tab has been navigated since the Observer was
492 // created. The standard TestNavigationObserver can only watch specific
493 // pre-existing tabs or loads in serial for all tabs.
494 class MultiNavigationObserver
: public content::NotificationObserver
{
496 MultiNavigationObserver();
497 virtual ~MultiNavigationObserver();
499 // Waits for exactly |num_navigations_to_wait_for| LOAD_STOP
500 // notifications to have occurred since the construction of |this|. More
501 // navigations than expected occuring will trigger a expect failure.
502 void WaitForNavigations(int num_navigations_to_wait_for
);
504 // Returns the number of LOAD_STOP events that have occurred for
505 // |web_contents| since this was constructed.
506 int NumNavigationsForTab(WebContents
* web_contents
) const;
508 // The number of LOAD_STOP events since |this| was created.
509 int num_navigations() const { return num_navigations_
; }
512 typedef std::map
<const WebContents
*, int> TabNavigationMap
;
514 // content::NotificationObserver:
515 virtual void Observe(int type
, const content::NotificationSource
& source
,
516 const content::NotificationDetails
& details
) OVERRIDE
;
518 int num_navigations_
;
520 // Map of how many times each tab has navigated since |this| was created.
521 TabNavigationMap tab_navigation_map_
;
523 // Total number of navigations to wait for. Value only matters when
524 // |waiting_for_navigation_| is true.
525 int num_navigations_to_wait_for_
;
527 // True if WaitForNavigations has been called, until
528 // |num_navigations_to_wait_for_| have been observed.
529 bool waiting_for_navigation_
;
531 content::NotificationRegistrar registrar_
;
533 DISALLOW_COPY_AND_ASSIGN(MultiNavigationObserver
);
536 MultiNavigationObserver::MultiNavigationObserver()
537 : num_navigations_(0),
538 num_navigations_to_wait_for_(0),
539 waiting_for_navigation_(false) {
540 registrar_
.Add(this, content::NOTIFICATION_LOAD_STOP
,
541 content::NotificationService::AllSources());
544 MultiNavigationObserver::~MultiNavigationObserver() {
547 void MultiNavigationObserver::WaitForNavigations(
548 int num_navigations_to_wait_for
) {
549 // Shouldn't already be waiting for navigations.
550 EXPECT_FALSE(waiting_for_navigation_
);
551 EXPECT_LT(0, num_navigations_to_wait_for
);
552 if (num_navigations_
< num_navigations_to_wait_for
) {
553 num_navigations_to_wait_for_
= num_navigations_to_wait_for
;
554 waiting_for_navigation_
= true;
555 content::RunMessageLoop();
556 EXPECT_FALSE(waiting_for_navigation_
);
558 EXPECT_EQ(num_navigations_
, num_navigations_to_wait_for
);
561 int MultiNavigationObserver::NumNavigationsForTab(
562 WebContents
* web_contents
) const {
563 TabNavigationMap::const_iterator tab_navigations
=
564 tab_navigation_map_
.find(web_contents
);
565 if (tab_navigations
== tab_navigation_map_
.end())
567 return tab_navigations
->second
;
570 void MultiNavigationObserver::Observe(
572 const content::NotificationSource
& source
,
573 const content::NotificationDetails
& details
) {
574 ASSERT_EQ(type
, content::NOTIFICATION_LOAD_STOP
);
575 content::NavigationController
* controller
=
576 content::Source
<content::NavigationController
>(source
).ptr();
578 ++tab_navigation_map_
[controller
->GetWebContents()];
579 if (waiting_for_navigation_
&&
580 num_navigations_to_wait_for_
== num_navigations_
) {
581 waiting_for_navigation_
= false;
582 MessageLoopForUI::current()->Quit();
586 // This observer creates a list of loading tabs, and then waits for them all
587 // to stop loading and have the kInternetConnectedTitle.
589 // This is for the specific purpose of observing tabs time out after logging in
590 // to a captive portal, which will then cause them to reload.
591 // MultiNavigationObserver is insufficient for this because there may or may not
592 // be a LOAD_STOP event between the timeout and the reload.
593 // See bug http://crbug.com/133227
594 class FailLoadsAfterLoginObserver
: public content::NotificationObserver
{
596 FailLoadsAfterLoginObserver();
597 virtual ~FailLoadsAfterLoginObserver();
599 void WaitForNavigations();
602 typedef std::set
<const WebContents
*> TabSet
;
604 // content::NotificationObserver:
605 virtual void Observe(int type
, const content::NotificationSource
& source
,
606 const content::NotificationDetails
& details
) OVERRIDE
;
608 // The set of tabs that need to be navigated. This is the set of loading
609 // tabs when the observer is created.
610 TabSet tabs_needing_navigation_
;
612 // Number of tabs that have stopped navigating with the expected title. These
613 // are expected not to be navigated again.
614 TabSet tabs_navigated_to_final_destination_
;
616 // True if WaitForNavigations has been called, until
617 // |tabs_navigated_to_final_destination_| equals |tabs_needing_navigation_|.
618 bool waiting_for_navigation_
;
620 content::NotificationRegistrar registrar_
;
622 DISALLOW_COPY_AND_ASSIGN(FailLoadsAfterLoginObserver
);
625 FailLoadsAfterLoginObserver::FailLoadsAfterLoginObserver()
626 : waiting_for_navigation_(false) {
627 registrar_
.Add(this, content::NOTIFICATION_LOAD_STOP
,
628 content::NotificationService::AllSources());
629 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
631 tabs_needing_navigation_
.insert(*it
);
635 FailLoadsAfterLoginObserver::~FailLoadsAfterLoginObserver() {
638 void FailLoadsAfterLoginObserver::WaitForNavigations() {
639 // Shouldn't already be waiting for navigations.
640 EXPECT_FALSE(waiting_for_navigation_
);
641 if (tabs_needing_navigation_
.size() !=
642 tabs_navigated_to_final_destination_
.size()) {
643 waiting_for_navigation_
= true;
644 content::RunMessageLoop();
645 EXPECT_FALSE(waiting_for_navigation_
);
647 EXPECT_EQ(tabs_needing_navigation_
.size(),
648 tabs_navigated_to_final_destination_
.size());
651 void FailLoadsAfterLoginObserver::Observe(
653 const content::NotificationSource
& source
,
654 const content::NotificationDetails
& details
) {
655 ASSERT_EQ(type
, content::NOTIFICATION_LOAD_STOP
);
656 content::NavigationController
* controller
=
657 content::Source
<content::NavigationController
>(source
).ptr();
658 WebContents
* contents
= controller
->GetWebContents();
660 ASSERT_EQ(1u, tabs_needing_navigation_
.count(contents
));
661 ASSERT_EQ(0u, tabs_navigated_to_final_destination_
.count(contents
));
663 if (contents
->GetTitle() != ASCIIToUTF16(kInternetConnectedTitle
))
665 tabs_navigated_to_final_destination_
.insert(contents
);
667 if (waiting_for_navigation_
&&
668 tabs_needing_navigation_
.size() ==
669 tabs_navigated_to_final_destination_
.size()) {
670 waiting_for_navigation_
= false;
671 MessageLoopForUI::current()->Quit();
675 // An observer for watching the CaptivePortalService. It tracks the last
676 // received result and the total number of received results.
677 class CaptivePortalObserver
: public content::NotificationObserver
{
679 explicit CaptivePortalObserver(Profile
* profile
);
681 // Runs the message loop until until at exactly |update_count| capitive portal
682 // results have been received, since this creation of |this|. Expects no
683 // additional captive portal results.
684 void WaitForResults(int num_results_to_wait_for
);
686 int num_results_received() const { return num_results_received_
; }
688 Result
captive_portal_result() const {
689 return captive_portal_result_
;
693 // Records results and exits the message loop, if needed.
694 virtual void Observe(int type
,
695 const content::NotificationSource
& source
,
696 const content::NotificationDetails
& details
) OVERRIDE
;
698 // Number of times OnPortalResult has been called since construction.
699 int num_results_received_
;
701 // If WaitForResults was called, the total number of updates for which to
702 // wait. Value doesn't matter when |waiting_for_result_| is false.
703 int num_results_to_wait_for_
;
705 bool waiting_for_result_
;
709 CaptivePortalService
* captive_portal_service_
;
711 // Last result received.
712 Result captive_portal_result_
;
714 content::NotificationRegistrar registrar_
;
716 DISALLOW_COPY_AND_ASSIGN(CaptivePortalObserver
);
719 CaptivePortalObserver::CaptivePortalObserver(Profile
* profile
)
720 : num_results_received_(0),
721 num_results_to_wait_for_(0),
722 waiting_for_result_(false),
724 captive_portal_service_(
725 CaptivePortalServiceFactory::GetForProfile(profile
)),
726 captive_portal_result_(
727 captive_portal_service_
->last_detection_result()) {
729 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
,
730 content::Source
<Profile
>(profile_
));
733 void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for
) {
734 EXPECT_LT(0, num_results_to_wait_for
);
735 EXPECT_FALSE(waiting_for_result_
);
736 if (num_results_received_
< num_results_to_wait_for
) {
737 num_results_to_wait_for_
= num_results_to_wait_for
;
738 waiting_for_result_
= true;
739 content::RunMessageLoop();
740 EXPECT_FALSE(waiting_for_result_
);
742 EXPECT_EQ(num_results_to_wait_for
, num_results_received_
);
745 void CaptivePortalObserver::Observe(
747 const content::NotificationSource
& source
,
748 const content::NotificationDetails
& details
) {
749 ASSERT_EQ(type
, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
);
750 ASSERT_EQ(profile_
, content::Source
<Profile
>(source
).ptr());
752 CaptivePortalService::Results
* results
=
753 content::Details
<CaptivePortalService::Results
>(details
).ptr();
755 EXPECT_EQ(captive_portal_result_
, results
->previous_result
);
756 EXPECT_EQ(captive_portal_service_
->last_detection_result(),
759 captive_portal_result_
= results
->result
;
760 ++num_results_received_
;
762 if (waiting_for_result_
&&
763 num_results_to_wait_for_
== num_results_received_
) {
764 waiting_for_result_
= false;
765 MessageLoop::current()->Quit();
769 // Adds an HSTS rule for |host|, so that all HTTP requests sent to it will
770 // be switched to HTTPS requests.
771 void AddHstsHost(net::URLRequestContextGetter
* context_getter
,
772 const std::string
& host
) {
773 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
774 net::TransportSecurityState
* transport_security_state
=
775 context_getter
->GetURLRequestContext()->transport_security_state();
776 if (!transport_security_state
) {
781 base::Time expiry
= base::Time::Now() + base::TimeDelta::FromDays(1000);
782 bool include_subdomains
= false;
783 transport_security_state
->AddHSTS(host
, expiry
, include_subdomains
);
788 class CaptivePortalBrowserTest
: public InProcessBrowserTest
{
790 CaptivePortalBrowserTest();
792 // InProcessBrowserTest:
793 virtual void SetUpOnMainThread() OVERRIDE
;
794 virtual void CleanUpOnMainThread() OVERRIDE
;
796 // Sets the captive portal checking preference. Does not affect the command
797 // line flag, which is set in SetUpCommandLine.
798 void EnableCaptivePortalDetection(Profile
* profile
, bool enabled
);
800 // Sets up the captive portal service for the given profile so that
801 // all checks go to |test_url|. Also disables all timers.
802 void SetUpCaptivePortalService(Profile
* profile
, const GURL
& test_url
);
804 // Returns true if |browser|'s profile is currently running a captive portal
806 bool CheckPending(Browser
* browser
);
808 // Returns the CaptivePortalTabReloader::State of |web_contents|.
809 CaptivePortalTabReloader::State
GetStateOfTabReloader(
810 WebContents
* web_contents
) const;
812 // Returns the CaptivePortalTabReloader::State of the indicated tab.
813 CaptivePortalTabReloader::State
GetStateOfTabReloaderAt(Browser
* browser
,
816 // Returns the number of tabs with the given state, across all profiles.
817 int NumTabsWithState(CaptivePortalTabReloader::State state
) const;
819 // Returns the number of tabs broken by captive portals, across all profiles.
820 int NumBrokenTabs() const;
822 // Returns the number of tabs that need to be reloaded due to having logged
823 // in to a captive portal, across all profiles.
824 int NumNeedReloadTabs() const;
826 // Navigates |browser|'s active tab to |url| and expects no captive portal
827 // test to be triggered. |expected_navigations| is the number of times the
828 // active tab will end up being navigated. It should be 1, except for the
829 // Link Doctor page, which acts like two navigations.
830 void NavigateToPageExpectNoTest(Browser
* browser
,
832 int expected_navigations
);
834 // Navigates |browser|'s active tab to an SSL tab that takes a while to load,
835 // triggering a captive portal check, which is expected to give the result
836 // |expected_result|. The page finishes loading, with a timeout, after the
837 // captive portal check.
838 void SlowLoadNoCaptivePortal(Browser
* browser
, Result expected_result
);
840 // Navigates |browser|'s active tab to an SSL timeout, expecting a captive
841 // portal check to be triggered and return a result which will indicates
842 // there's no detected captive portal.
843 void FastTimeoutNoCaptivePortal(Browser
* browser
, Result expected_result
);
845 // Navigates the active tab to a slow loading SSL page, which will then
846 // trigger a captive portal test. The test is expected to find a captive
847 // portal. The slow loading page will continue to load after the function
848 // returns, until URLRequestTimeoutOnDemandJob::FailJobs() is called,
849 // at which point it will timeout.
851 // When |expect_login_tab| is false, no login tab is expected to be opened,
852 // because one already exists, and the function returns once the captive
853 // portal test is complete.
855 // If |expect_login_tab| is true, a login tab is then expected to be opened.
856 // It waits until both the login tab has finished loading, and two captive
857 // portal tests complete. The second test is triggered by the load of the
858 // captive portal tab completing.
860 // This function must not be called when the active tab is currently loading.
861 // Waits for the hanging request to be issued, so other functions can rely
862 // on URLRequestTimeoutOnDemandJob::WaitForJobs having been called.
863 void SlowLoadBehindCaptivePortal(Browser
* browser
, bool expect_login_tab
);
865 // Same as above, but takes extra parameters.
867 // |hanging_url| should either be kMockHttpsUrl or redirect to kMockHttpsUrl.
869 // |expected_portal_checks| and |expected_login_tab_navigations| allow
870 // client-side redirects to be tested. |expected_login_tab_navigations| is
871 // ignored when |expect_open_login_tab| is false.
872 void SlowLoadBehindCaptivePortal(Browser
* browser
,
873 bool expect_open_login_tab
,
874 const GURL
& hanging_url
,
875 int expected_portal_checks
,
876 int expected_login_tab_navigations
);
878 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has
879 // a connection timeout rather having its time trigger, and the function
880 // waits until that timeout occurs.
881 void FastTimeoutBehindCaptivePortal(Browser
* browser
,
882 bool expect_open_login_tab
);
884 // Much as above, but accepts a URL parameter and can be used for errors that
885 // trigger captive portal checks other than timeouts. |error_url| should
886 // result in an error rather than hanging.
887 void FastErrorBehindCaptivePortal(Browser
* browser
,
888 bool expect_open_login_tab
,
889 const GURL
& error_url
);
891 // Navigates the login tab without logging in. The login tab must be the
892 // specified browser's active tab. Expects no other tab to change state.
893 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
894 // that nothing has gone wrong prior to the function call.
895 void NavigateLoginTab(Browser
* browser
,
896 int num_loading_tabs
,
897 int num_timed_out_tabs
);
899 // Simulates a login by updating the URLRequestMockCaptivePortalJob's
900 // behind captive portal state, and navigating the login tab. Waits for
901 // all broken but not loading tabs to be reloaded.
902 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
903 // that nothing has gone wrong prior to the function call.
904 void Login(Browser
* browser
, int num_loading_tabs
, int num_timed_out_tabs
);
906 // Makes the slow SSL loads of all active tabs time out at once, and waits for
907 // them to finish both that load and the automatic reload it should trigger.
908 // There should be no timed out tabs when this is called.
909 void FailLoadsAfterLogin(Browser
* browser
, int num_loading_tabs
);
911 // Makes the slow SSL loads of all active tabs time out at once, and waits for
912 // them to finish displaying their error pages. The login tab should be the
913 // active tab. There should be no timed out tabs when this is called.
914 void FailLoadsWithoutLogin(Browser
* browser
, int num_loading_tabs
);
916 // Navigates |browser|'s active tab to |starting_url| while not behind a
917 // captive portal. Then navigates to |interrupted_url|, which should create
918 // a URLRequestTimeoutOnDemandJob, which is then abandoned. The load should
919 // trigger a captive portal check, which finds a captive portal and opens a
922 // Then the navigation is interrupted by a navigation to |timeout_url|, which
923 // should trigger a captive portal check, and finally the test simulates
926 // The purpose of this test is to make sure the TabHelper triggers a captive
927 // portal check when a load is interrupted by another load, particularly in
928 // the case of cross-process navigations.
929 void RunNavigateLoadingTabToTimeoutTest(Browser
* browser
,
930 const GURL
& starting_url
,
931 const GURL
& interrupted_url
,
932 const GURL
& timeout_url
);
934 // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads
935 // before a captive portal check.
936 void SetSlowSSLLoadTime(CaptivePortalTabReloader
* tab_reloader
,
937 base::TimeDelta slow_ssl_load_time
);
939 CaptivePortalTabReloader
* GetTabReloader(WebContents
* web_contents
) const;
942 DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest
);
945 CaptivePortalBrowserTest::CaptivePortalBrowserTest() {
948 void CaptivePortalBrowserTest::SetUpOnMainThread() {
949 // Enable mock requests.
950 content::BrowserThread::PostTask(
951 content::BrowserThread::IO
, FROM_HERE
,
952 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
953 URLRequestMockCaptivePortalJobFactory::AddUrlHandlers();
955 // Double-check that the captive portal service isn't enabled by default for
957 EXPECT_EQ(CaptivePortalService::DISABLED_FOR_TESTING
,
958 CaptivePortalService::get_state_for_testing());
960 CaptivePortalService::set_state_for_testing(
961 CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING
);
962 EnableCaptivePortalDetection(browser()->profile(), true);
964 // Set the captive portal service to use URLRequestMockCaptivePortalJob's
965 // mock URL, by default.
966 SetUpCaptivePortalService(browser()->profile(),
967 GURL(kMockCaptivePortalTestUrl
));
970 void CaptivePortalBrowserTest::CleanUpOnMainThread() {
971 // No test should have a captive portal check pending on quit.
972 EXPECT_FALSE(CheckPending(browser()));
975 void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
976 Profile
* profile
, bool enabled
) {
977 profile
->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled
, enabled
);
980 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile
* profile
,
981 const GURL
& test_url
) {
982 CaptivePortalService
* captive_portal_service
=
983 CaptivePortalServiceFactory::GetForProfile(profile
);
984 captive_portal_service
->set_test_url(test_url
);
986 // Don't use any non-zero timers. Timers are checked in unit tests.
987 CaptivePortalService::RecheckPolicy
* recheck_policy
=
988 &captive_portal_service
->recheck_policy();
989 recheck_policy
->initial_backoff_no_portal_ms
= 0;
990 recheck_policy
->initial_backoff_portal_ms
= 0;
991 recheck_policy
->backoff_policy
.maximum_backoff_ms
= 0;
994 bool CaptivePortalBrowserTest::CheckPending(Browser
* browser
) {
995 CaptivePortalService
* captive_portal_service
=
996 CaptivePortalServiceFactory::GetForProfile(browser
->profile());
998 return captive_portal_service
->DetectionInProgress() ||
999 captive_portal_service
->TimerRunning();
1002 CaptivePortalTabReloader::State
CaptivePortalBrowserTest::GetStateOfTabReloader(
1003 WebContents
* web_contents
) const {
1004 return GetTabReloader(web_contents
)->state();
1007 CaptivePortalTabReloader::State
1008 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser
* browser
,
1010 return GetStateOfTabReloader(
1011 browser
->tab_strip_model()->GetWebContentsAt(index
));
1014 int CaptivePortalBrowserTest::NumTabsWithState(
1015 CaptivePortalTabReloader::State state
) const {
1017 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
1018 if (GetStateOfTabReloader(*it
) == state
)
1024 int CaptivePortalBrowserTest::NumBrokenTabs() const {
1025 return NumTabsWithState(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
);
1028 int CaptivePortalBrowserTest::NumNeedReloadTabs() const {
1029 return NumTabsWithState(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
);
1032 void CaptivePortalBrowserTest::NavigateToPageExpectNoTest(
1035 int expected_navigations
) {
1036 MultiNavigationObserver navigation_observer
;
1037 CaptivePortalObserver
portal_observer(browser
->profile());
1039 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
1040 browser
, url
, expected_navigations
);
1042 // No captive portal checks should have ocurred or be pending, and there
1043 // should be no new tabs.
1044 EXPECT_EQ(0, portal_observer
.num_results_received());
1045 EXPECT_FALSE(CheckPending(browser
));
1046 EXPECT_EQ(1, browser
->tab_strip_model()->count());
1047 EXPECT_EQ(expected_navigations
, navigation_observer
.num_navigations());
1048 EXPECT_EQ(0, NumLoadingTabs());
1049 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1050 GetStateOfTabReloaderAt(browser
, 0));
1053 void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal(
1054 Browser
* browser
, Result expected_result
) {
1055 CaptivePortalTabReloader
* tab_reloader
=
1056 GetTabReloader(browser
->tab_strip_model()->GetActiveWebContents());
1057 ASSERT_TRUE(tab_reloader
);
1058 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
1060 MultiNavigationObserver navigation_observer
;
1061 CaptivePortalObserver
portal_observer(browser
->profile());
1062 ui_test_utils::NavigateToURLWithDisposition(browser
,
1063 GURL(kMockHttpsUrl
),
1065 ui_test_utils::BROWSER_TEST_NONE
);
1067 portal_observer
.WaitForResults(1);
1069 ASSERT_EQ(1, browser
->tab_strip_model()->count());
1070 EXPECT_EQ(expected_result
, portal_observer
.captive_portal_result());
1071 EXPECT_EQ(1, portal_observer
.num_results_received());
1072 EXPECT_EQ(0, navigation_observer
.num_navigations());
1073 EXPECT_FALSE(CheckPending(browser
));
1075 // First tab should still be loading.
1076 EXPECT_EQ(1, NumLoadingTabs());
1078 // Wait for the request to be issued, then time it out.
1079 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1080 URLRequestTimeoutOnDemandJob::FailJobs(1);
1081 navigation_observer
.WaitForNavigations(1);
1083 ASSERT_EQ(1, browser
->tab_strip_model()->count());
1084 EXPECT_EQ(1, portal_observer
.num_results_received());
1085 EXPECT_FALSE(CheckPending(browser
));
1086 EXPECT_EQ(0, NumLoadingTabs());
1088 // Set a slow SSL load time to prevent the timer from triggering.
1089 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
1092 void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal(
1093 Browser
* browser
, Result expected_result
) {
1094 ASSERT_NE(expected_result
, RESULT_BEHIND_CAPTIVE_PORTAL
);
1096 // Set the load time to be large, so the timer won't trigger. The value is
1097 // not restored at the end of the function.
1098 CaptivePortalTabReloader
* tab_reloader
=
1099 GetTabReloader(browser
->tab_strip_model()->GetActiveWebContents());
1100 ASSERT_TRUE(tab_reloader
);
1101 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromHours(1));
1103 MultiNavigationObserver navigation_observer
;
1104 CaptivePortalObserver
portal_observer(browser
->profile());
1106 // Neither of these should be changed by the navigation.
1107 int active_index
= browser
->tab_strip_model()->active_index();
1108 int expected_tab_count
= browser
->tab_strip_model()->count();
1110 ui_test_utils::NavigateToURL(
1112 URLRequestFailedJob::GetMockHttpsUrl(net::ERR_CONNECTION_TIMED_OUT
));
1114 // An attempt to detect a captive portal should have started by now. If not,
1115 // abort early to prevent hanging.
1116 ASSERT_TRUE(portal_observer
.num_results_received() > 0 ||
1117 CheckPending(browser
));
1119 portal_observer
.WaitForResults(1);
1120 navigation_observer
.WaitForNavigations(1);
1122 // Check the result.
1123 EXPECT_EQ(1, portal_observer
.num_results_received());
1124 EXPECT_EQ(expected_result
, portal_observer
.captive_portal_result());
1126 // Check that the right tab was navigated, and there were no extra
1128 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1129 browser
->tab_strip_model()->GetWebContentsAt(active_index
)));
1130 EXPECT_EQ(0, NumLoadingTabs());
1132 // Check the tab's state, and verify no captive portal check is pending.
1133 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1134 GetStateOfTabReloaderAt(browser
, 0));
1135 EXPECT_FALSE(CheckPending(browser
));
1137 // Make sure no login tab was opened.
1138 EXPECT_EQ(expected_tab_count
, browser
->tab_strip_model()->count());
1141 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
1143 bool expect_open_login_tab
) {
1144 SlowLoadBehindCaptivePortal(browser
,
1145 expect_open_login_tab
,
1146 GURL(kMockHttpsUrl
),
1151 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
1153 bool expect_open_login_tab
,
1154 const GURL
& hanging_url
,
1155 int expected_portal_checks
,
1156 int expected_login_tab_navigations
) {
1157 ASSERT_GE(expected_portal_checks
, 1);
1158 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1159 // Calling this on a tab that's waiting for a load to manually be timed out
1160 // will result in a hang.
1161 ASSERT_FALSE(tab_strip_model
->GetActiveWebContents()->IsLoading());
1163 // Trigger a captive portal check quickly.
1164 CaptivePortalTabReloader
* tab_reloader
=
1165 GetTabReloader(tab_strip_model
->GetActiveWebContents());
1166 ASSERT_TRUE(tab_reloader
);
1167 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
1169 // Number of tabs expected to be open after the captive portal checks
1171 int initial_tab_count
= tab_strip_model
->count();
1172 int initial_active_index
= tab_strip_model
->active_index();
1173 int initial_loading_tabs
= NumLoadingTabs();
1174 int expected_broken_tabs
= NumBrokenTabs();
1175 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
!=
1176 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents())) {
1177 ++expected_broken_tabs
;
1180 MultiNavigationObserver navigation_observer
;
1181 CaptivePortalObserver
portal_observer(browser
->profile());
1182 ui_test_utils::NavigateToURLWithDisposition(browser
,
1185 ui_test_utils::BROWSER_TEST_NONE
);
1186 portal_observer
.WaitForResults(expected_portal_checks
);
1188 if (expect_open_login_tab
) {
1189 ASSERT_GE(expected_login_tab_navigations
, 1);
1191 navigation_observer
.WaitForNavigations(expected_login_tab_navigations
);
1193 ASSERT_EQ(initial_tab_count
+ 1, tab_strip_model
->count());
1194 EXPECT_EQ(initial_tab_count
, tab_strip_model
->active_index());
1196 EXPECT_EQ(expected_login_tab_navigations
,
1197 navigation_observer
.NumNavigationsForTab(
1198 tab_strip_model
->GetWebContentsAt(initial_tab_count
)));
1199 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1200 GetStateOfTabReloaderAt(browser
, 1));
1201 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1203 EXPECT_EQ(0, navigation_observer
.num_navigations());
1204 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1205 ASSERT_EQ(initial_tab_count
, tab_strip_model
->count());
1206 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1209 // Wait for all the expect resource loads to actually start, so subsequent
1210 // functions can rely on them having started.
1211 URLRequestTimeoutOnDemandJob::WaitForJobs(initial_loading_tabs
+ 1);
1213 EXPECT_EQ(initial_loading_tabs
+ 1, NumLoadingTabs());
1214 EXPECT_EQ(expected_broken_tabs
, NumBrokenTabs());
1215 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL
,
1216 portal_observer
.captive_portal_result());
1217 EXPECT_EQ(expected_portal_checks
, portal_observer
.num_results_received());
1218 EXPECT_FALSE(CheckPending(browser
));
1220 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1221 GetStateOfTabReloaderAt(browser
, initial_active_index
));
1223 // Reset the load time to be large, so the timer won't trigger on a reload.
1224 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromHours(1));
1227 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
1229 bool expect_open_login_tab
) {
1230 FastErrorBehindCaptivePortal(browser
,
1231 expect_open_login_tab
,
1232 GURL(kMockHttpsQuickTimeoutUrl
));
1235 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
1237 bool expect_open_login_tab
,
1238 const GURL
& error_url
) {
1239 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1240 // Calling this on a tab that's waiting for a load to manually be timed out
1241 // will result in a hang.
1242 ASSERT_FALSE(tab_strip_model
->GetActiveWebContents()->IsLoading());
1244 // Set the load time to be large, so the timer won't trigger. The value is
1245 // not restored at the end of the function.
1246 CaptivePortalTabReloader
* tab_reloader
=
1247 GetTabReloader(tab_strip_model
->GetActiveWebContents());
1248 ASSERT_TRUE(tab_reloader
);
1249 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromHours(1));
1251 // Number of tabs expected to be open after the captive portal checks
1253 int initial_tab_count
= tab_strip_model
->count();
1254 int initial_active_index
= tab_strip_model
->active_index();
1255 int initial_loading_tabs
= NumLoadingTabs();
1256 int expected_broken_tabs
= NumBrokenTabs();
1257 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
!=
1258 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents())) {
1259 ++expected_broken_tabs
;
1262 MultiNavigationObserver navigation_observer
;
1263 CaptivePortalObserver
portal_observer(browser
->profile());
1264 ui_test_utils::NavigateToURLWithDisposition(browser
,
1267 ui_test_utils::BROWSER_TEST_NONE
);
1268 portal_observer
.WaitForResults(1);
1270 if (expect_open_login_tab
) {
1271 navigation_observer
.WaitForNavigations(2);
1272 ASSERT_EQ(initial_tab_count
+ 1, tab_strip_model
->count());
1273 EXPECT_EQ(initial_tab_count
, tab_strip_model
->active_index());
1274 // Make sure that the originally active tab and the captive portal tab have
1275 // each loaded once.
1276 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1277 tab_strip_model
->GetWebContentsAt(initial_active_index
)));
1278 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1279 tab_strip_model
->GetWebContentsAt(initial_tab_count
)));
1280 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1281 GetStateOfTabReloaderAt(browser
, 1));
1282 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1284 navigation_observer
.WaitForNavigations(1);
1285 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1286 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1287 tab_strip_model
->GetWebContentsAt(initial_active_index
)));
1288 ASSERT_EQ(initial_tab_count
, tab_strip_model
->count());
1289 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1292 EXPECT_EQ(initial_loading_tabs
, NumLoadingTabs());
1293 EXPECT_EQ(expected_broken_tabs
, NumBrokenTabs());
1294 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL
,
1295 portal_observer
.captive_portal_result());
1296 EXPECT_EQ(1, portal_observer
.num_results_received());
1297 EXPECT_FALSE(CheckPending(browser
));
1299 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1300 GetStateOfTabReloaderAt(browser
, initial_active_index
));
1303 void CaptivePortalBrowserTest::NavigateLoginTab(Browser
* browser
,
1304 int num_loading_tabs
,
1305 int num_timed_out_tabs
) {
1306 MultiNavigationObserver navigation_observer
;
1307 CaptivePortalObserver
portal_observer(browser
->profile());
1309 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1310 int initial_tab_count
= tab_strip_model
->count();
1311 EXPECT_EQ(num_loading_tabs
, NumLoadingTabs());
1312 EXPECT_EQ(num_timed_out_tabs
, NumBrokenTabs() - NumLoadingTabs());
1314 int login_tab_index
= tab_strip_model
->active_index();
1315 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1316 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents()));
1317 ASSERT_TRUE(IsLoginTab(browser
->tab_strip_model()->GetActiveWebContents()));
1319 // Do the navigation.
1320 content::RenderViewHost
* render_view_host
=
1321 tab_strip_model
->GetActiveWebContents()->GetRenderViewHost();
1322 render_view_host
->ExecuteJavascriptInWebFrame(string16(),
1323 ASCIIToUTF16("submitForm()"));
1325 portal_observer
.WaitForResults(1);
1326 navigation_observer
.WaitForNavigations(1);
1328 // Check the captive portal result.
1329 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL
,
1330 portal_observer
.captive_portal_result());
1331 EXPECT_EQ(1, portal_observer
.num_results_received());
1332 EXPECT_FALSE(CheckPending(browser
));
1334 // Make sure not much has changed.
1335 EXPECT_EQ(initial_tab_count
, tab_strip_model
->count());
1336 EXPECT_EQ(num_loading_tabs
, NumLoadingTabs());
1337 EXPECT_EQ(num_loading_tabs
+ num_timed_out_tabs
, NumBrokenTabs());
1338 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1339 GetStateOfTabReloaderAt(browser
, login_tab_index
));
1340 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1342 // Make sure there were no unexpected navigations.
1343 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1344 tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1347 void CaptivePortalBrowserTest::Login(Browser
* browser
,
1348 int num_loading_tabs
,
1349 int num_timed_out_tabs
) {
1350 // Simulate logging in.
1351 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1353 MultiNavigationObserver navigation_observer
;
1354 CaptivePortalObserver
portal_observer(browser
->profile());
1356 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1357 int initial_tab_count
= tab_strip_model
->count();
1358 ASSERT_EQ(num_loading_tabs
, NumLoadingTabs());
1359 EXPECT_EQ(num_timed_out_tabs
, NumBrokenTabs() - NumLoadingTabs());
1361 // Verify that the login page is on top.
1362 int login_tab_index
= tab_strip_model
->active_index();
1363 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1364 GetStateOfTabReloaderAt(browser
, login_tab_index
));
1365 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1367 // Trigger a navigation.
1368 content::RenderViewHost
* render_view_host
=
1369 tab_strip_model
->GetActiveWebContents()->GetRenderViewHost();
1370 render_view_host
->ExecuteJavascriptInWebFrame(string16(),
1371 ASCIIToUTF16("submitForm()"));
1373 portal_observer
.WaitForResults(1);
1375 // Wait for all the timed out tabs to reload.
1376 navigation_observer
.WaitForNavigations(1 + num_timed_out_tabs
);
1377 EXPECT_EQ(1, portal_observer
.num_results_received());
1379 // The tabs that were loading before should still be loading, and now be in
1380 // STATE_NEEDS_RELOAD.
1381 EXPECT_EQ(0, NumBrokenTabs());
1382 EXPECT_EQ(num_loading_tabs
, NumLoadingTabs());
1383 EXPECT_EQ(num_loading_tabs
, NumNeedReloadTabs());
1385 // Make sure that the broken tabs have reloaded, and there's no more
1386 // captive portal tab.
1387 EXPECT_EQ(initial_tab_count
, tab_strip_model
->count());
1388 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1389 GetStateOfTabReloaderAt(browser
, login_tab_index
));
1390 EXPECT_FALSE(IsLoginTab(tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1392 // Make sure there were no unexpected navigations of the login tab.
1393 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1394 tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1397 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser
* browser
,
1398 int num_loading_tabs
) {
1399 ASSERT_EQ(num_loading_tabs
, NumLoadingTabs());
1400 ASSERT_EQ(num_loading_tabs
, NumNeedReloadTabs());
1401 EXPECT_EQ(0, NumBrokenTabs());
1403 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1404 int initial_num_tabs
= tab_strip_model
->count();
1405 int initial_active_tab
= tab_strip_model
->active_index();
1407 CaptivePortalObserver
portal_observer(browser
->profile());
1408 FailLoadsAfterLoginObserver fail_loads_observer
;
1409 // Connection(s) finally time out. There should have already been a call
1410 // to wait for the requests to be issued before logging on.
1411 URLRequestTimeoutOnDemandJob::WaitForJobs(num_loading_tabs
);
1412 URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs
);
1414 fail_loads_observer
.WaitForNavigations();
1416 // No captive portal checks should have ocurred or be pending, and there
1417 // should be no new tabs.
1418 EXPECT_EQ(0, portal_observer
.num_results_received());
1419 EXPECT_FALSE(CheckPending(browser
));
1420 EXPECT_EQ(initial_num_tabs
, tab_strip_model
->count());
1422 EXPECT_EQ(initial_active_tab
, tab_strip_model
->active_index());
1424 EXPECT_EQ(0, NumNeedReloadTabs());
1425 EXPECT_EQ(0, NumLoadingTabs());
1428 void CaptivePortalBrowserTest::FailLoadsWithoutLogin(Browser
* browser
,
1429 int num_loading_tabs
) {
1430 ASSERT_EQ(num_loading_tabs
, NumLoadingTabs());
1431 ASSERT_EQ(0, NumNeedReloadTabs());
1432 EXPECT_EQ(num_loading_tabs
, NumBrokenTabs());
1434 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1435 int initial_num_tabs
= tab_strip_model
->count();
1436 int login_tab
= tab_strip_model
->active_index();
1437 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1438 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents()));
1439 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetActiveWebContents()));
1441 CaptivePortalObserver
portal_observer(browser
->profile());
1442 MultiNavigationObserver navigation_observer
;
1443 // Connection(s) finally time out. There should have already been a call
1444 // to wait for the requests to be issued.
1445 URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs
);
1447 navigation_observer
.WaitForNavigations(num_loading_tabs
);
1449 // No captive portal checks should have ocurred or be pending, and there
1450 // should be no new tabs.
1451 EXPECT_EQ(0, portal_observer
.num_results_received());
1452 EXPECT_FALSE(CheckPending(browser
));
1453 EXPECT_EQ(initial_num_tabs
, tab_strip_model
->count());
1455 EXPECT_EQ(0, NumNeedReloadTabs());
1456 EXPECT_EQ(0, NumLoadingTabs());
1457 EXPECT_EQ(num_loading_tabs
, NumBrokenTabs());
1458 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1459 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents()));
1460 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetActiveWebContents()));
1461 EXPECT_EQ(login_tab
, tab_strip_model
->active_index());
1463 EXPECT_EQ(0, navigation_observer
.NumNavigationsForTab(
1464 tab_strip_model
->GetWebContentsAt(login_tab
)));
1467 void CaptivePortalBrowserTest::RunNavigateLoadingTabToTimeoutTest(
1469 const GURL
& starting_url
,
1470 const GURL
& hanging_url
,
1471 const GURL
& timeout_url
) {
1472 // Temporarily disable the captive portal and navigate to the starting
1473 // URL, which may be a URL that will hang when behind a captive portal.
1474 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1475 NavigateToPageExpectNoTest(browser
, starting_url
, 1);
1476 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
1478 // Go to the first hanging url.
1479 SlowLoadBehindCaptivePortal(browser
, true, hanging_url
, 1, 1);
1481 // Abandon the request.
1482 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1483 URLRequestTimeoutOnDemandJob::AbandonJobs(1);
1485 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1486 CaptivePortalTabReloader
* tab_reloader
=
1487 GetTabReloader(tab_strip_model
->GetWebContentsAt(0));
1488 ASSERT_TRUE(tab_reloader
);
1490 // A non-zero delay makes it more likely that CaptivePortalTabHelper will
1491 // be confused by events relating to canceling the old navigation.
1492 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromSeconds(2));
1493 CaptivePortalObserver
portal_observer(browser
->profile());
1495 // Navigate the error tab to another slow loading page. Can't have
1496 // ui_test_utils do the navigation because it will wait for loading tabs to
1497 // stop loading before navigating.
1499 // This may result in either 0 or 1 DidStopLoading events. If there is one,
1500 // it must happen before the CaptivePortalService sends out its test request,
1501 // so waiting for PortalObserver to see that request prevents it from
1502 // confusing the MultiNavigationObservers used later.
1503 tab_strip_model
->ActivateTabAt(0, true);
1504 browser
->OpenURL(content::OpenURLParams(timeout_url
,
1505 content::Referrer(),
1507 content::PAGE_TRANSITION_TYPED
,
1509 portal_observer
.WaitForResults(1);
1510 EXPECT_FALSE(CheckPending(browser
));
1511 EXPECT_EQ(1, NumLoadingTabs());
1512 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1513 GetStateOfTabReloaderAt(browser
, 0));
1514 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1515 GetStateOfTabReloaderAt(browser
, 1));
1516 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1518 // Need to make sure the request has been issued before logging in.
1519 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1521 // Simulate logging in.
1522 tab_strip_model
->ActivateTabAt(1, true);
1523 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
1524 Login(browser
, 1, 0);
1526 // Timeout occurs, and page is automatically reloaded.
1527 FailLoadsAfterLogin(browser
, 1);
1530 void CaptivePortalBrowserTest::SetSlowSSLLoadTime(
1531 CaptivePortalTabReloader
* tab_reloader
,
1532 base::TimeDelta slow_ssl_load_time
) {
1533 tab_reloader
->set_slow_ssl_load_time(slow_ssl_load_time
);
1536 CaptivePortalTabReloader
* CaptivePortalBrowserTest::GetTabReloader(
1537 WebContents
* web_contents
) const {
1538 return CaptivePortalTabHelper::FromWebContents(web_contents
)->
1539 GetTabReloaderForTest();
1542 // Make sure there's no test for a captive portal on HTTP timeouts. This will
1543 // also trigger the link doctor page, which results in the load of a second
1545 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpTimeout
) {
1546 GURL url
= URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT
);
1547 NavigateToPageExpectNoTest(browser(), url
, 2);
1550 // Make sure there's no check for a captive portal on HTTPS errors other than
1551 // timeouts, when they preempt the slow load timer.
1552 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpsNonTimeoutError
) {
1553 GURL url
= URLRequestFailedJob::GetMockHttpsUrl(net::ERR_UNEXPECTED
);
1554 NavigateToPageExpectNoTest(browser(), url
, 1);
1557 // Make sure no captive portal test triggers on HTTPS timeouts of iframes.
1558 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpsIframeTimeout
) {
1559 // Use an HTTPS server for the top level page.
1560 net::TestServer
https_server(
1561 net::TestServer::TYPE_HTTPS
, net::TestServer::kLocalhost
,
1562 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1563 ASSERT_TRUE(https_server
.Start());
1565 GURL url
= https_server
.GetURL(kTestServerIframeTimeoutPath
);
1566 NavigateToPageExpectNoTest(browser(), url
, 1);
1569 // Check the captive portal result when the test request reports a network
1570 // error. The check is triggered by a slow loading page, and the page
1571 // errors out only after getting a captive portal result.
1572 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, RequestFails
) {
1573 SetUpCaptivePortalService(
1574 browser()->profile(),
1575 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED
));
1576 SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE
);
1579 // Same as above, but for the rather unlikely case that the connection times out
1580 // before the timer triggers.
1581 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, RequestFailsFastTimout
) {
1582 SetUpCaptivePortalService(
1583 browser()->profile(),
1584 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED
));
1585 FastTimeoutNoCaptivePortal(browser(), RESULT_NO_RESPONSE
);
1588 // Checks the case that captive portal detection is disabled.
1589 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, Disabled
) {
1590 EnableCaptivePortalDetection(browser()->profile(), false);
1591 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED
);
1594 // Checks that we look for a captive portal on HTTPS timeouts and don't reload
1595 // the error tab when the captive portal probe gets a 204 response, indicating
1596 // there is no captive portal.
1597 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, InternetConnected
) {
1598 // Can't just use SetBehindCaptivePortal(false), since then there wouldn't
1600 ASSERT_TRUE(test_server()->Start());
1601 SetUpCaptivePortalService(browser()->profile(),
1602 test_server()->GetURL("nocontent"));
1603 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED
);
1606 // Checks that no login page is opened when the HTTP test URL redirects to an
1607 // SSL certificate error.
1608 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, RedirectSSLCertError
) {
1609 // Need an HTTP TestServer to handle a dynamically created server redirect.
1610 ASSERT_TRUE(test_server()->Start());
1612 net::TestServer::SSLOptions ssl_options
;
1613 ssl_options
.server_certificate
=
1614 net::TestServer::SSLOptions::CERT_MISMATCHED_NAME
;
1615 net::TestServer
https_server(
1616 net::TestServer::TYPE_HTTPS
, ssl_options
,
1617 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1618 ASSERT_TRUE(https_server
.Start());
1620 GURL ssl_login_url
= https_server
.GetURL(kTestServerLoginPath
);
1622 CaptivePortalService
* captive_portal_service
=
1623 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
1624 ASSERT_TRUE(captive_portal_service
);
1625 SetUpCaptivePortalService(
1626 browser()->profile(),
1627 test_server()->GetURL(CreateServerRedirect(ssl_login_url
.spec())));
1629 SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE
);
1632 // A slow SSL load triggers a captive portal check. The user logs on before
1633 // the SSL page times out. We wait for the timeout and subsequent reload.
1634 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, Login
) {
1635 // Load starts, detect captive portal and open up a login tab.
1636 SlowLoadBehindCaptivePortal(browser(), true);
1638 // Log in. One loading tab, no timed out ones.
1639 Login(browser(), 1, 0);
1641 // Timeout occurs, and page is automatically reloaded.
1642 FailLoadsAfterLogin(browser(), 1);
1645 // Same as above, except we make sure everything works with an incognito
1646 // profile. Main issues it tests for are that the incognito has its own
1647 // non-NULL captive portal service, and we open the tab in the correct
1649 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginIncognito
) {
1650 // This will watch tabs for both profiles, but only used to make sure no
1651 // navigations occur for the non-incognito profile.
1652 MultiNavigationObserver navigation_observer
;
1653 CaptivePortalObserver
non_incognito_portal_observer(browser()->profile());
1655 Browser
* incognito_browser
= CreateIncognitoBrowser();
1656 EnableCaptivePortalDetection(incognito_browser
->profile(), true);
1657 SetUpCaptivePortalService(incognito_browser
->profile(),
1658 GURL(kMockCaptivePortalTestUrl
));
1660 SlowLoadBehindCaptivePortal(incognito_browser
, true);
1662 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1663 EXPECT_EQ(1, tab_strip_model
->count());
1664 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1665 GetStateOfTabReloaderAt(browser(), 0));
1667 Login(incognito_browser
, 1, 0);
1668 FailLoadsAfterLogin(incognito_browser
, 1);
1670 EXPECT_EQ(1, tab_strip_model
->count());
1671 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1672 GetStateOfTabReloaderAt(browser(), 0));
1674 EXPECT_EQ(0, navigation_observer
.NumNavigationsForTab(
1675 tab_strip_model
->GetWebContentsAt(0)));
1676 EXPECT_EQ(0, non_incognito_portal_observer
.num_results_received());
1679 // The captive portal page is opened before the SSL page times out,
1680 // but the user logs in only after the page times out.
1681 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginSlow
) {
1682 SlowLoadBehindCaptivePortal(browser(), true);
1683 FailLoadsWithoutLogin(browser(), 1);
1684 Login(browser(), 0, 1);
1687 // Checks the unlikely case that the tab times out before the timer triggers.
1688 // This most likely won't happen, but should still work:
1689 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginFastTimeout
) {
1690 FastTimeoutBehindCaptivePortal(browser(), true);
1691 Login(browser(), 0, 1);
1694 // A cert error triggers a captive portal check and results in opening a login
1695 // tab. The user then logs in and the page with the error is reloaded.
1696 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, SSLCertErrorLogin
) {
1697 // Need an HTTP TestServer to handle a dynamically created server redirect.
1698 ASSERT_TRUE(test_server()->Start());
1700 net::TestServer::SSLOptions https_options
;
1701 https_options
.server_certificate
=
1702 net::TestServer::SSLOptions::CERT_MISMATCHED_NAME
;
1703 net::TestServer
https_server(
1704 net::TestServer::TYPE_HTTPS
, https_options
,
1705 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1706 ASSERT_TRUE(https_server
.Start());
1708 // The path does not matter.
1709 GURL cert_error_url
= https_server
.GetURL(kTestServerLoginPath
);
1710 // The interstitial should trigger a captive portal check when it opens, just
1711 // like navigating to kMockHttpsQuickTimeoutUrl.
1712 FastErrorBehindCaptivePortal(browser(), true, cert_error_url
);
1714 // Simulate logging in. Can't use Login() because the interstitial tab looks
1715 // like a cross between a hung tab (Load was never committed) and a tab at an
1716 // error page (The load was stopped).
1717 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1718 MultiNavigationObserver navigation_observer
;
1719 CaptivePortalObserver
portal_observer(browser()->profile());
1721 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1722 content::RenderViewHost
* render_view_host
=
1723 tab_strip_model
->GetActiveWebContents()->GetRenderViewHost();
1724 render_view_host
->ExecuteJavascriptInWebFrame(
1726 ASCIIToUTF16("submitForm()"));
1728 // The captive portal tab navigation will trigger a captive portal check,
1729 // and reloading the original tab will bring up the interstitial page again,
1730 // triggering a second captive portal check.
1731 portal_observer
.WaitForResults(2);
1733 // Wait for both tabs to finish loading.
1734 navigation_observer
.WaitForNavigations(2);
1735 EXPECT_EQ(2, portal_observer
.num_results_received());
1736 EXPECT_FALSE(CheckPending(browser()));
1737 EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED
,
1738 portal_observer
.captive_portal_result());
1740 // Check state of tabs. While the first tab is still displaying an
1741 // interstitial page, since no portal was found, it should be in STATE_NONE,
1742 // as should the login tab.
1743 ASSERT_EQ(2, tab_strip_model
->count());
1744 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1745 GetStateOfTabReloaderAt(browser(), 0));
1746 EXPECT_FALSE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1747 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1748 GetStateOfTabReloaderAt(browser(), 1));
1750 // Make sure only one navigation was for the login tab.
1751 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1752 tab_strip_model
->GetWebContentsAt(1)));
1755 // Tries navigating both the tab that encounters an SSL timeout and the
1756 // login tab twice, only logging in the second time.
1757 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginExtraNavigations
) {
1758 FastTimeoutBehindCaptivePortal(browser(), true);
1760 // Activate the timed out tab and navigate it to a timeout again.
1761 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1762 tab_strip_model
->ActivateTabAt(0, true);
1763 FastTimeoutBehindCaptivePortal(browser(), false);
1765 // Activate and navigate the captive portal tab. This should not trigger a
1766 // reload of the tab with the error.
1767 tab_strip_model
->ActivateTabAt(1, true);
1768 NavigateLoginTab(browser(), 0, 1);
1770 // Simulate logging in.
1771 Login(browser(), 0, 1);
1774 // After the first SSL timeout, closes the login tab and makes sure it's opened
1775 // it again on a second timeout.
1776 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, CloseLoginTab
) {
1777 // First load starts, opens a login tab, and then times out.
1778 SlowLoadBehindCaptivePortal(browser(), true);
1779 FailLoadsWithoutLogin(browser(), 1);
1782 chrome::CloseTab(browser());
1784 // Go through the standard slow load login, and make sure it still works.
1785 SlowLoadBehindCaptivePortal(browser(), true);
1786 Login(browser(), 1, 0);
1787 FailLoadsAfterLogin(browser(), 1);
1790 // Checks that two tabs with SSL timeouts in the same window work. Both
1791 // tabs only timeout after logging in.
1792 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, TwoBrokenTabs
) {
1793 SlowLoadBehindCaptivePortal(browser(), true);
1795 // Can't set the TabReloader HTTPS timeout on a new tab without doing some
1796 // acrobatics, so open a new tab at a normal page, and then navigate it to a
1798 MultiNavigationObserver navigation_observer
;
1799 CaptivePortalObserver
portal_observer(browser()->profile());
1800 ui_test_utils::NavigateToURLWithDisposition(
1802 URLRequestMockHTTPJob::GetMockUrl(
1803 base::FilePath(FILE_PATH_LITERAL("title2.html"))),
1805 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1807 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1808 ASSERT_EQ(3, tab_strip_model
->count());
1809 EXPECT_FALSE(CheckPending(browser()));
1810 EXPECT_EQ(0, portal_observer
.num_results_received());
1811 EXPECT_EQ(1, NumLoadingTabs());
1812 EXPECT_EQ(1, navigation_observer
.num_navigations());
1813 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1814 tab_strip_model
->GetWebContentsAt(2)));
1815 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1816 GetStateOfTabReloaderAt(browser(), 0));
1817 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1818 GetStateOfTabReloaderAt(browser(), 1));
1819 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1820 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1821 GetStateOfTabReloaderAt(browser(), 2));
1822 ASSERT_EQ(2, tab_strip_model
->active_index());
1824 SlowLoadBehindCaptivePortal(browser(), false);
1826 tab_strip_model
->ActivateTabAt(1, true);
1827 Login(browser(), 2, 0);
1828 FailLoadsAfterLogin(browser(), 2);
1831 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, AbortLoad
) {
1832 SlowLoadBehindCaptivePortal(browser(), true);
1834 // Abandon the request.
1835 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1836 URLRequestTimeoutOnDemandJob::AbandonJobs(1);
1838 CaptivePortalObserver
portal_observer(browser()->profile());
1839 MultiNavigationObserver navigation_observer
;
1841 // Switch back to the hung tab from the login tab, and abort the navigation.
1842 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1843 tab_strip_model
->ActivateTabAt(0, true);
1844 chrome::Stop(browser());
1845 navigation_observer
.WaitForNavigations(1);
1847 EXPECT_EQ(0, NumBrokenTabs());
1848 EXPECT_EQ(0, portal_observer
.num_results_received());
1849 EXPECT_FALSE(CheckPending(browser()));
1850 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1851 GetStateOfTabReloaderAt(browser(), 0));
1853 tab_strip_model
->ActivateTabAt(1, true);
1854 Login(browser(), 0, 0);
1857 // Checks the case where the timed out tab is successfully navigated before
1859 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, NavigateBrokenTab
) {
1860 // Go to the error page.
1861 SlowLoadBehindCaptivePortal(browser(), true);
1862 FailLoadsWithoutLogin(browser(), 1);
1864 // Navigate the error tab to a non-error page.
1865 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1866 tab_strip_model
->ActivateTabAt(0, true);
1867 ui_test_utils::NavigateToURL(
1868 browser(), URLRequestMockHTTPJob::GetMockUrl(
1869 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
1870 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1871 GetStateOfTabReloaderAt(browser(), 0));
1873 // Simulate logging in.
1874 tab_strip_model
->ActivateTabAt(1, true);
1875 Login(browser(), 0, 0);
1878 // Checks that captive portal detection triggers correctly when a same-site
1879 // navigation is cancelled by a navigation to the same site.
1880 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
,
1881 NavigateLoadingTabToTimeoutSingleSite
) {
1882 RunNavigateLoadingTabToTimeoutTest(
1884 GURL(kMockHttpsUrl
),
1885 GURL(kMockHttpsUrl
),
1886 GURL(kMockHttpsUrl
));
1889 // Fails on Windows only, mostly on Win7. http://crbug.com/170033
1891 #define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
1892 DISABLED_NavigateLoadingTabToTimeoutTwoSites
1894 #define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
1895 NavigateLoadingTabToTimeoutTwoSites
1898 // Checks that captive portal detection triggers correctly when a same-site
1899 // navigation is cancelled by a navigation to another site.
1900 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
,
1901 MAYBE_NavigateLoadingTabToTimeoutTwoSites
) {
1902 RunNavigateLoadingTabToTimeoutTest(
1904 GURL(kMockHttpsUrl
),
1905 GURL(kMockHttpsUrl
),
1906 GURL(kMockHttpsUrl2
));
1909 // Checks that captive portal detection triggers correctly when a cross-site
1910 // navigation is cancelled by a navigation to yet another site.
1911 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
,
1912 NavigateLoadingTabToTimeoutThreeSites
) {
1913 RunNavigateLoadingTabToTimeoutTest(
1915 URLRequestMockHTTPJob::GetMockUrl(
1916 base::FilePath(FILE_PATH_LITERAL("title.html"))),
1917 GURL(kMockHttpsUrl
),
1918 GURL(kMockHttpsUrl2
));
1921 // Checks that navigating a timed out tab back clears its state.
1922 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, GoBack
) {
1923 // Navigate to a working page.
1924 ui_test_utils::NavigateToURL(
1926 URLRequestMockHTTPJob::GetMockUrl(
1927 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
1929 // Go to the error page.
1930 SlowLoadBehindCaptivePortal(browser(), true);
1931 FailLoadsWithoutLogin(browser(), 1);
1933 CaptivePortalObserver
portal_observer(browser()->profile());
1934 MultiNavigationObserver navigation_observer
;
1936 // Activate the error page tab again and go back.
1937 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1938 tab_strip_model
->ActivateTabAt(0, true);
1939 chrome::GoBack(browser(), CURRENT_TAB
);
1940 navigation_observer
.WaitForNavigations(1);
1942 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1943 tab_strip_model
->GetWebContentsAt(0)));
1944 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1945 GetStateOfTabReloaderAt(browser(), 0));
1946 EXPECT_EQ(0, portal_observer
.num_results_received());
1949 // Checks that navigating back to a timeout triggers captive portal detection.
1950 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, GoBackToTimeout
) {
1951 // Disable captive portal detection so the first navigation doesn't open a
1953 EnableCaptivePortalDetection(browser()->profile(), false);
1955 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED
);
1957 // Navigate to a working page.
1958 ui_test_utils::NavigateToURL(
1959 browser(), URLRequestMockHTTPJob::GetMockUrl(
1960 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
1961 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1962 GetStateOfTabReloaderAt(browser(), 0));
1964 EnableCaptivePortalDetection(browser()->profile(), true);
1966 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1967 CaptivePortalTabReloader
* tab_reloader
=
1968 GetTabReloader(tab_strip_model
->GetActiveWebContents());
1969 ASSERT_TRUE(tab_reloader
);
1970 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
1972 // Go to the error page.
1973 MultiNavigationObserver navigation_observer
;
1974 CaptivePortalObserver
portal_observer(browser()->profile());
1975 chrome::GoBack(browser(), CURRENT_TAB
);
1977 // Wait for the check triggered by the broken tab and for the login tab to
1979 portal_observer
.WaitForResults(1);
1980 navigation_observer
.WaitForNavigations(1);
1981 // Make sure the request has been issued.
1982 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1984 EXPECT_EQ(1, portal_observer
.num_results_received());
1985 ASSERT_FALSE(CheckPending(browser()));
1986 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL
,
1987 portal_observer
.captive_portal_result());
1989 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1990 GetStateOfTabReloaderAt(browser(), 0));
1991 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1992 GetStateOfTabReloaderAt(browser(), 1));
1993 ASSERT_TRUE(IsLoginTab(browser()->tab_strip_model()->GetWebContentsAt(1)));
1995 ASSERT_EQ(2, tab_strip_model
->count());
1996 EXPECT_EQ(1, tab_strip_model
->active_index());
1997 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1998 tab_strip_model
->GetWebContentsAt(1)));
1999 EXPECT_EQ(1, NumLoadingTabs());
2001 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
2002 Login(browser(), 1, 0);
2003 FailLoadsAfterLogin(browser(), 1);
2006 // Checks that reloading a timeout triggers captive portal detection.
2007 // Much like the last test, though the captive portal is disabled before
2008 // the inital navigation, rather than captive portal detection.
2009 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, ReloadTimeout
) {
2010 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
2012 // Do the first navigation while not behind a captive portal.
2013 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
2014 CaptivePortalObserver
portal_observer(browser()->profile());
2015 ui_test_utils::NavigateToURL(browser(), GURL(kMockHttpsUrl
));
2016 ASSERT_EQ(0, portal_observer
.num_results_received());
2017 ASSERT_EQ(1, tab_strip_model
->count());
2019 // A captive portal spontaneously appears.
2020 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
2022 CaptivePortalTabReloader
* tab_reloader
=
2023 GetTabReloader(tab_strip_model
->GetActiveWebContents());
2024 ASSERT_TRUE(tab_reloader
);
2025 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
2027 MultiNavigationObserver navigation_observer
;
2028 tab_strip_model
->GetActiveWebContents()->GetController().Reload(true);
2030 // Wait for the check triggered by the broken tab and for the login tab to
2032 portal_observer
.WaitForResults(1);
2033 navigation_observer
.WaitForNavigations(1);
2034 // Make sure the request has been issued.
2035 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
2037 ASSERT_EQ(1, portal_observer
.num_results_received());
2038 ASSERT_FALSE(CheckPending(browser()));
2039 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL
,
2040 portal_observer
.captive_portal_result());
2042 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
2043 GetStateOfTabReloaderAt(browser(), 0));
2044 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2045 GetStateOfTabReloaderAt(browser(), 1));
2046 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
2048 ASSERT_EQ(2, tab_strip_model
->count());
2049 EXPECT_EQ(1, tab_strip_model
->active_index());
2050 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
2051 tab_strip_model
->GetWebContentsAt(1)));
2052 EXPECT_EQ(1, NumLoadingTabs());
2054 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
2055 Login(browser(), 1, 0);
2056 FailLoadsAfterLogin(browser(), 1);
2059 // Checks the case where there are two windows, and there's an SSL timeout in
2060 // the background one.
2061 // Disabled: http://crbug.com/134357
2062 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, DISABLED_TwoWindows
) {
2064 new Browser(Browser::CreateParams(browser()->profile(),
2065 browser()->host_desktop_type()));
2066 // Navigate the new browser window so it'll be shown and we can pick the
2068 ui_test_utils::NavigateToURL(browser2
, GURL(chrome::kAboutBlankURL
));
2070 // Generally, |browser2| will be the active window. However, if the
2071 // original browser window lost focus before creating the new one, such as
2072 // when running multiple tests at once, the original browser window may
2073 // remain the profile's active window.
2074 Browser
* active_browser
=
2075 chrome::FindTabbedBrowser(browser()->profile(), true,
2076 browser()->host_desktop_type());
2077 Browser
* inactive_browser
;
2078 if (active_browser
== browser2
) {
2079 // When only one test is running at a time, the new browser will probably be
2080 // on top, but when multiple tests are running at once, this is not
2082 inactive_browser
= browser();
2084 ASSERT_EQ(active_browser
, browser());
2085 inactive_browser
= browser2
;
2088 CaptivePortalObserver
portal_observer(browser()->profile());
2089 MultiNavigationObserver navigation_observer
;
2091 // Navigate the tab in the inactive browser to an SSL timeout. Have to use
2092 // chrome::NavigateParams and NEW_BACKGROUND_TAB to avoid activating the
2094 chrome::NavigateParams
params(inactive_browser
,
2095 GURL(kMockHttpsQuickTimeoutUrl
),
2096 content::PAGE_TRANSITION_TYPED
);
2097 params
.disposition
= NEW_BACKGROUND_TAB
;
2098 params
.window_action
= chrome::NavigateParams::NO_ACTION
;
2099 ui_test_utils::NavigateToURL(¶ms
);
2100 navigation_observer
.WaitForNavigations(2);
2102 // Make sure the active window hasn't changed, and its new tab is
2104 ASSERT_EQ(active_browser
,
2105 chrome::FindTabbedBrowser(browser()->profile(), true,
2106 browser()->host_desktop_type()));
2107 ASSERT_EQ(1, active_browser
->tab_strip_model()->active_index());
2109 // Check that the only two navigated tabs were the new error tab in the
2110 // backround windows, and the login tab in the active window.
2111 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
2112 inactive_browser
->tab_strip_model()->GetWebContentsAt(1)));
2113 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
2114 active_browser
->tab_strip_model()->GetWebContentsAt(1)));
2115 EXPECT_EQ(0, NumLoadingTabs());
2117 // Check captive portal test results.
2118 portal_observer
.WaitForResults(1);
2119 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL
,
2120 portal_observer
.captive_portal_result());
2121 EXPECT_EQ(1, portal_observer
.num_results_received());
2123 // Check the inactive browser.
2124 EXPECT_EQ(2, inactive_browser
->tab_strip_model()->count());
2125 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2126 GetStateOfTabReloaderAt(inactive_browser
, 0));
2127 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
2128 GetStateOfTabReloaderAt(inactive_browser
, 1));
2130 // Check the active browser.
2131 ASSERT_EQ(2, active_browser
->tab_strip_model()->count());
2132 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2133 GetStateOfTabReloaderAt(active_browser
, 0));
2134 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2135 GetStateOfTabReloaderAt(active_browser
, 1));
2137 IsLoginTab(active_browser
->tab_strip_model()->GetWebContentsAt(1)));
2139 // Simulate logging in.
2140 Login(active_browser
, 0, 1);
2143 // An HTTP page redirects to an HTTPS page loads slowly before timing out. A
2144 // captive portal is found, and then the user logs in before the original page
2146 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpToHttpsRedirectLogin
) {
2147 ASSERT_TRUE(test_server()->Start());
2148 SlowLoadBehindCaptivePortal(
2151 test_server()->GetURL(CreateServerRedirect(kMockHttpsUrl
)),
2154 Login(browser(), 1, 0);
2155 FailLoadsAfterLogin(browser(), 1);
2158 // An HTTPS page redirects to an HTTP page.
2159 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpsToHttpRedirect
) {
2160 // Use an HTTPS server for the top level page.
2161 net::TestServer
https_server(
2162 net::TestServer::TYPE_HTTPS
, net::TestServer::kLocalhost
,
2163 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2164 ASSERT_TRUE(https_server
.Start());
2166 GURL http_timeout_url
=
2167 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT
);
2169 // 2 navigations due to the Link Doctor.
2170 NavigateToPageExpectNoTest(
2172 https_server
.GetURL(CreateServerRedirect(http_timeout_url
.spec())),
2176 // Tests the 511 response code, along with an HTML redirect to a login page.
2177 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, Status511
) {
2178 SetUpCaptivePortalService(browser()->profile(),
2179 GURL(kMockCaptivePortal511Url
));
2180 SlowLoadBehindCaptivePortal(browser(), true, GURL(kMockHttpsUrl
), 2, 2);
2181 Login(browser(), 1, 0);
2182 FailLoadsAfterLogin(browser(), 1);
2185 // HSTS redirects an HTTP request to HTTPS, and the request then times out.
2186 // A captive portal is then detected, and a login tab opened, before logging
2188 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HstsLogin
) {
2189 GURL::Replacements replacements
;
2190 std::string scheme
= "http";
2191 replacements
.SetSchemeStr(scheme
);
2192 GURL http_timeout_url
= GURL(kMockHttpsUrl
).ReplaceComponents(replacements
);
2194 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT
);
2195 content::BrowserThread::PostTask(
2196 content::BrowserThread::IO
, FROM_HERE
,
2197 base::Bind(&AddHstsHost
,
2198 make_scoped_refptr(browser()->profile()->GetRequestContext()),
2199 http_timeout_url
.host()));
2201 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url
, 1, 1);
2202 Login(browser(), 1, 0);
2203 FailLoadsAfterLogin(browser(), 1);
2206 } // namespace captive_portal