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/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/strings/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/chrome_notification_types.h"
22 #include "chrome/browser/net/url_request_mock_util.h"
23 #include "chrome/browser/profiles/profile.h"
24 #include "chrome/browser/ui/browser.h"
25 #include "chrome/browser/ui/browser_commands.h"
26 #include "chrome/browser/ui/browser_finder.h"
27 #include "chrome/browser/ui/browser_navigator.h"
28 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
29 #include "chrome/browser/ui/tabs/tab_strip_model.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_frame_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 captive_portal::CaptivePortalResult
;
57 using content::BrowserThread
;
58 using content::URLRequestFailedJob
;
59 using content::URLRequestMockHTTPJob
;
60 using content::WebContents
;
64 // Path of the fake login page, when using the TestServer.
65 const char* const kTestServerLoginPath
= "files/captive_portal/login.html";
67 // Path of a page with an iframe that has a mock SSL timeout, when using the
69 const char* const kTestServerIframeTimeoutPath
=
70 "files/captive_portal/iframe_timeout.html";
72 // The following URLs each have two different behaviors, depending on whether
73 // URLRequestMockCaptivePortalJobFactory is currently simulating the presence
74 // of a captive portal or not. They use different domains so that HSTS can be
75 // applied to them independently.
77 // A mock URL for the CaptivePortalService's |test_url|. When behind a captive
78 // portal, this URL returns a mock login page. When connected to the Internet,
79 // it returns a 204 response. Uses the name of the login file so that reloading
80 // it will not request a different URL.
81 const char* const kMockCaptivePortalTestUrl
=
82 "http://mock.captive.portal.test/login.html";
84 // Another mock URL for the CaptivePortalService's |test_url|. When behind a
85 // captive portal, this URL returns a 511 status code and an HTML page that
86 // redirect to the above URL. When connected to the Internet, it returns a 204
88 const char* const kMockCaptivePortal511Url
=
89 "http://mock.captive.portal.511/page511.html";
91 // When behind a captive portal, this URL hangs without committing until a call
92 // to URLRequestTimeoutOnDemandJob::FailJobs. When that function is called,
93 // the request will time out.
95 // When connected to the Internet, this URL returns a non-error page.
96 const char* const kMockHttpsUrl
=
97 "https://mock.captive.portal.long.timeout/title2.html";
99 // Same as above, but different domain, so can be used to trigger cross-site
101 const char* const kMockHttpsUrl2
=
102 "https://mock.captive.portal.long.timeout2/title2.html";
104 // Same as kMockHttpsUrl, except the timeout happens instantly.
105 const char* const kMockHttpsQuickTimeoutUrl
=
106 "https://mock.captive.portal.quick.timeout/title2.html";
108 // Expected title of a tab once an HTTPS load completes, when not behind a
110 const char* const kInternetConnectedTitle
= "Title Of Awesomeness";
112 // A URL request job that hangs until FailJobs() is called. Started jobs
113 // are stored in a static class variable containing a linked list so that
114 // FailJobs() can locate them.
115 class URLRequestTimeoutOnDemandJob
: public net::URLRequestJob
,
116 public base::NonThreadSafe
{
118 // net::URLRequestJob:
119 virtual void Start() OVERRIDE
;
121 // All the public static methods below can be called on any thread.
123 // Waits for exactly |num_jobs|.
124 static void WaitForJobs(int num_jobs
);
126 // Fails all active URLRequestTimeoutOnDemandJobs with connection timeouts.
127 // There are expected to be exactly |expected_num_jobs| waiting for
128 // failure. The only way to gaurantee this is with an earlier call to
129 // WaitForJobs, so makes sure there has been a matching WaitForJobs call.
130 static void FailJobs(int expected_num_jobs
);
132 // Abandon all active URLRequestTimeoutOnDemandJobs. |expected_num_jobs|
133 // behaves just as in FailJobs.
134 static void AbandonJobs(int expected_num_jobs
);
137 friend class URLRequestMockCaptivePortalJobFactory
;
139 // Operation to perform on jobs when removing them from |job_list_|.
140 enum EndJobOperation
{
145 URLRequestTimeoutOnDemandJob(net::URLRequest
* request
,
146 net::NetworkDelegate
* network_delegate
);
147 virtual ~URLRequestTimeoutOnDemandJob();
149 // Attempts to removes |this| from |jobs_|. Returns true if it was removed
151 bool RemoveFromList();
153 static void WaitForJobsOnIOThread(int num_jobs
);
154 static void FailOrAbandonJobsOnIOThread(
155 int expected_num_jobs
,
156 EndJobOperation end_job_operation
);
158 // Checks if there are at least |num_jobs_to_wait_for_| jobs in
159 // |job_list_|. If so, exits the message loop on the UI thread, which
160 // should be spinning in a call to WaitForJobs. Does nothing when
161 // |num_jobs_to_wait_for_| is 0.
162 static void MaybeStopWaitingForJobsOnIOThread();
164 // All class variables are only accessed on the IO thread.
166 // Number of jobs currently being waited for, or 0 if not currently
168 static int num_jobs_to_wait_for_
;
170 // The last number of jobs that were waited for. When FailJobs or
171 // AbandonJobs is called, this should match |expected_num_jobs|.
172 static int last_num_jobs_to_wait_for_
;
174 // Number of jobs that have been started, but not yet waited for. If jobs
175 // are deleted unexpectedly, they're still included in this count, even though
176 // they've been removed from |job_list_|. Intended to reduce chance of stalls
178 static int num_jobs_started_
;
180 // Head of linked list of jobs that have been started and are now waiting to
182 static URLRequestTimeoutOnDemandJob
* job_list_
;
184 // The next job that had been started but not yet timed out.
185 URLRequestTimeoutOnDemandJob
* next_job_
;
187 DISALLOW_COPY_AND_ASSIGN(URLRequestTimeoutOnDemandJob
);
190 int URLRequestTimeoutOnDemandJob::num_jobs_to_wait_for_
= 0;
191 int URLRequestTimeoutOnDemandJob::last_num_jobs_to_wait_for_
= 0;
192 int URLRequestTimeoutOnDemandJob::num_jobs_started_
= 0;
193 URLRequestTimeoutOnDemandJob
* URLRequestTimeoutOnDemandJob::job_list_
= NULL
;
195 void URLRequestTimeoutOnDemandJob::Start() {
196 EXPECT_TRUE(CalledOnValidThread());
198 // Insert at start of the list.
199 next_job_
= job_list_
;
203 // Checks if there are at least |num_jobs_to_wait_for_| jobs in
204 // |job_list_|. If so, exits the message loop on the UI thread, which
205 // should be spinning in a call to WaitForJobs. Does nothing if
206 // |num_jobs_to_wait_for_| is 0.
207 MaybeStopWaitingForJobsOnIOThread();
211 void URLRequestTimeoutOnDemandJob::WaitForJobs(int num_jobs
) {
212 content::BrowserThread::PostTask(
213 content::BrowserThread::IO
, FROM_HERE
,
214 base::Bind(&URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread
,
216 content::RunMessageLoop();
220 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs
) {
221 content::BrowserThread::PostTask(
222 content::BrowserThread::IO
, FROM_HERE
,
223 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread
,
229 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs
) {
230 content::BrowserThread::PostTask(
231 content::BrowserThread::IO
, FROM_HERE
,
232 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread
,
237 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
238 net::URLRequest
* request
, net::NetworkDelegate
* network_delegate
)
239 : net::URLRequestJob(request
, network_delegate
),
243 URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() {
244 // All hanging jobs should have failed or been abandoned before being
246 EXPECT_FALSE(RemoveFromList());
249 bool URLRequestTimeoutOnDemandJob::RemoveFromList() {
250 URLRequestTimeoutOnDemandJob
** job
= &job_list_
;
260 // If the job wasn't in this list, |next_job_| should be NULL.
261 EXPECT_FALSE(next_job_
);
266 void URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread(int num_jobs
) {
267 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
268 ASSERT_EQ(0, num_jobs_to_wait_for_
);
269 ASSERT_LT(0, num_jobs
);
270 // Number of tabs being waited on should be strictly increasing.
271 ASSERT_LE(last_num_jobs_to_wait_for_
, num_jobs
);
273 num_jobs_to_wait_for_
= num_jobs
;
274 MaybeStopWaitingForJobsOnIOThread();
278 void URLRequestTimeoutOnDemandJob::MaybeStopWaitingForJobsOnIOThread() {
279 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
280 if (num_jobs_to_wait_for_
== 0)
283 // There shouldn't be any extra jobs.
284 EXPECT_LE(num_jobs_started_
, num_jobs_to_wait_for_
);
286 // Should never be greater, but if it is, go ahead and exit the message loop
287 // to try and avoid hanging.
288 if (num_jobs_started_
>= num_jobs_to_wait_for_
) {
289 last_num_jobs_to_wait_for_
= num_jobs_to_wait_for_
;
290 num_jobs_to_wait_for_
= 0;
291 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
292 base::MessageLoop::QuitClosure());
297 void URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread(
298 int expected_num_jobs
,
299 EndJobOperation end_job_operation
) {
300 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
301 ASSERT_LT(0, expected_num_jobs
);
302 EXPECT_EQ(last_num_jobs_to_wait_for_
, expected_num_jobs
);
303 last_num_jobs_to_wait_for_
= 0;
308 URLRequestTimeoutOnDemandJob
* job
= job_list_
;
309 // Since the error notification may result in the job's destruction, remove
310 // it from the job list before the error.
311 EXPECT_TRUE(job
->RemoveFromList());
312 if (end_job_operation
== FAIL_JOBS
) {
313 job
->NotifyStartError(net::URLRequestStatus(
314 net::URLRequestStatus::FAILED
,
315 net::ERR_CONNECTION_TIMED_OUT
));
319 EXPECT_EQ(expected_num_jobs
, num_jobs_started_
);
320 EXPECT_EQ(expected_num_jobs
, num_jobs
);
322 num_jobs_started_
-= expected_num_jobs
;
325 // URLRequestCaptivePortalJobFactory emulates captive portal behavior.
326 // Initially, it emulates being behind a captive portal. When
327 // SetBehindCaptivePortal(false) is called, it emulates behavior when not behind
328 // a captive portal. The class itself is never instantiated.
330 // It handles requests for kMockCaptivePortalTestUrl, kMockHttpsUrl, and
331 // kMockHttpsQuickTimeoutUrl.
332 class URLRequestMockCaptivePortalJobFactory
{
334 // The public static methods below can be called on any thread.
336 // Adds the testing URLs to the net::URLRequestFilter. Should only be called
338 static void AddUrlHandlers();
340 // Sets whether or not there is a captive portal. Outstanding requests are
342 static void SetBehindCaptivePortal(bool behind_captive_portal
);
345 // These do all the work of the corresponding public functions, with the only
346 // difference being that they must be called on the IO thread.
347 static void AddUrlHandlersOnIOThread();
348 static void SetBehindCaptivePortalOnIOThread(bool behind_captive_portal
);
350 // Returns a URLRequestJob that reflects the current captive portal state
351 // for the URLs: kMockCaptivePortalTestUrl, kMockHttpsUrl, and
352 // kMockHttpsQuickTimeoutUrl. See documentation of individual URLs for
354 static net::URLRequestJob
* Factory(net::URLRequest
* request
,
355 net::NetworkDelegate
* network_delegate
,
356 const std::string
& scheme
);
358 static bool behind_captive_portal_
;
360 DISALLOW_IMPLICIT_CONSTRUCTORS(URLRequestMockCaptivePortalJobFactory
);
363 bool URLRequestMockCaptivePortalJobFactory::behind_captive_portal_
= true;
366 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() {
367 content::BrowserThread::PostTask(
368 content::BrowserThread::IO
, FROM_HERE
,
370 &URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread
));
374 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(
375 bool behind_captive_portal
) {
376 content::BrowserThread::PostTask(
377 content::BrowserThread::IO
, FROM_HERE
,
379 &URLRequestMockCaptivePortalJobFactory::
380 SetBehindCaptivePortalOnIOThread
,
381 behind_captive_portal
));
385 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() {
386 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
388 // Handle only exact matches, so any related requests, such as those for
389 // favicons, are not handled by the factory.
390 net::URLRequestFilter
* filter
= net::URLRequestFilter::GetInstance();
391 filter
->AddUrlHandler(GURL(kMockCaptivePortalTestUrl
),
392 URLRequestMockCaptivePortalJobFactory::Factory
);
393 filter
->AddUrlHandler(GURL(kMockCaptivePortal511Url
),
394 URLRequestMockCaptivePortalJobFactory::Factory
);
395 filter
->AddUrlHandler(GURL(kMockHttpsUrl
),
396 URLRequestMockCaptivePortalJobFactory::Factory
);
397 filter
->AddUrlHandler(GURL(kMockHttpsUrl2
),
398 URLRequestMockCaptivePortalJobFactory::Factory
);
399 filter
->AddUrlHandler(GURL(kMockHttpsQuickTimeoutUrl
),
400 URLRequestMockCaptivePortalJobFactory::Factory
);
404 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread(
405 bool behind_captive_portal
) {
406 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
407 behind_captive_portal_
= behind_captive_portal
;
411 net::URLRequestJob
* URLRequestMockCaptivePortalJobFactory::Factory(
412 net::URLRequest
* request
,
413 net::NetworkDelegate
* network_delegate
,
414 const std::string
& scheme
) {
415 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
417 // The PathService is threadsafe.
418 base::FilePath root_http
;
419 PathService::Get(chrome::DIR_TEST_DATA
, &root_http
);
421 if (request
->url() == GURL(kMockHttpsUrl
) ||
422 request
->url() == GURL(kMockHttpsUrl2
)) {
423 if (behind_captive_portal_
)
424 return new URLRequestTimeoutOnDemandJob(request
, network_delegate
);
425 // Once logged in to the portal, HTTPS requests return the page that was
426 // actually requested.
427 return new URLRequestMockHTTPJob(
430 root_http
.Append(FILE_PATH_LITERAL("title2.html")));
431 } else if (request
->url() == GURL(kMockHttpsQuickTimeoutUrl
)) {
432 if (behind_captive_portal_
)
433 return new URLRequestFailedJob(
434 request
, network_delegate
, net::ERR_CONNECTION_TIMED_OUT
);
435 // Once logged in to the portal, HTTPS requests return the page that was
436 // actually requested.
437 return new URLRequestMockHTTPJob(
440 root_http
.Append(FILE_PATH_LITERAL("title2.html")));
442 // The URL should be the captive portal test URL.
443 EXPECT_TRUE(GURL(kMockCaptivePortalTestUrl
) == request
->url() ||
444 GURL(kMockCaptivePortal511Url
) == request
->url());
446 if (behind_captive_portal_
) {
447 // Prior to logging in to the portal, the HTTP test URLs are intercepted
448 // by the captive portal.
449 if (GURL(kMockCaptivePortal511Url
) == request
->url()) {
450 return new URLRequestMockHTTPJob(
453 root_http
.Append(FILE_PATH_LITERAL("captive_portal/page511.html")));
455 return new URLRequestMockHTTPJob(
458 root_http
.Append(FILE_PATH_LITERAL("captive_portal/login.html")));
461 // After logging in to the portal, the test URLs return a 204 response.
462 return new URLRequestMockHTTPJob(
465 root_http
.Append(FILE_PATH_LITERAL("captive_portal/page204.html")));
469 // Creates a server-side redirect for use with the TestServer.
470 std::string
CreateServerRedirect(const std::string
& dest_url
) {
471 const char* const kServerRedirectBase
= "server-redirect?";
472 return kServerRedirectBase
+ dest_url
;
475 // Returns the total number of loading tabs across all Browsers, for all
477 int NumLoadingTabs() {
478 int num_loading_tabs
= 0;
479 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
483 return num_loading_tabs
;
486 bool IsLoginTab(WebContents
* web_contents
) {
487 return CaptivePortalTabHelper::FromWebContents(web_contents
)->IsLoginTab();
490 // Tracks how many times each tab has been navigated since the Observer was
491 // created. The standard TestNavigationObserver can only watch specific
492 // pre-existing tabs or loads in serial for all tabs.
493 class MultiNavigationObserver
: public content::NotificationObserver
{
495 MultiNavigationObserver();
496 virtual ~MultiNavigationObserver();
498 // Waits for exactly |num_navigations_to_wait_for| LOAD_STOP
499 // notifications to have occurred since the construction of |this|. More
500 // navigations than expected occuring will trigger a expect failure.
501 void WaitForNavigations(int num_navigations_to_wait_for
);
503 // Returns the number of LOAD_STOP events that have occurred for
504 // |web_contents| since this was constructed.
505 int NumNavigationsForTab(WebContents
* web_contents
) const;
507 // The number of LOAD_STOP events since |this| was created.
508 int num_navigations() const { return num_navigations_
; }
511 typedef std::map
<const WebContents
*, int> TabNavigationMap
;
513 // content::NotificationObserver:
514 virtual void Observe(int type
, const content::NotificationSource
& source
,
515 const content::NotificationDetails
& details
) OVERRIDE
;
517 int num_navigations_
;
519 // Map of how many times each tab has navigated since |this| was created.
520 TabNavigationMap tab_navigation_map_
;
522 // Total number of navigations to wait for. Value only matters when
523 // |waiting_for_navigation_| is true.
524 int num_navigations_to_wait_for_
;
526 // True if WaitForNavigations has been called, until
527 // |num_navigations_to_wait_for_| have been observed.
528 bool waiting_for_navigation_
;
530 content::NotificationRegistrar registrar_
;
532 DISALLOW_COPY_AND_ASSIGN(MultiNavigationObserver
);
535 MultiNavigationObserver::MultiNavigationObserver()
536 : num_navigations_(0),
537 num_navigations_to_wait_for_(0),
538 waiting_for_navigation_(false) {
539 registrar_
.Add(this, content::NOTIFICATION_LOAD_STOP
,
540 content::NotificationService::AllSources());
543 MultiNavigationObserver::~MultiNavigationObserver() {
546 void MultiNavigationObserver::WaitForNavigations(
547 int num_navigations_to_wait_for
) {
548 // Shouldn't already be waiting for navigations.
549 EXPECT_FALSE(waiting_for_navigation_
);
550 EXPECT_LT(0, num_navigations_to_wait_for
);
551 if (num_navigations_
< num_navigations_to_wait_for
) {
552 num_navigations_to_wait_for_
= num_navigations_to_wait_for
;
553 waiting_for_navigation_
= true;
554 content::RunMessageLoop();
555 EXPECT_FALSE(waiting_for_navigation_
);
557 EXPECT_EQ(num_navigations_
, num_navigations_to_wait_for
);
560 int MultiNavigationObserver::NumNavigationsForTab(
561 WebContents
* web_contents
) const {
562 TabNavigationMap::const_iterator tab_navigations
=
563 tab_navigation_map_
.find(web_contents
);
564 if (tab_navigations
== tab_navigation_map_
.end())
566 return tab_navigations
->second
;
569 void MultiNavigationObserver::Observe(
571 const content::NotificationSource
& source
,
572 const content::NotificationDetails
& details
) {
573 ASSERT_EQ(type
, content::NOTIFICATION_LOAD_STOP
);
574 content::NavigationController
* controller
=
575 content::Source
<content::NavigationController
>(source
).ptr();
577 ++tab_navigation_map_
[controller
->GetWebContents()];
578 if (waiting_for_navigation_
&&
579 num_navigations_to_wait_for_
== num_navigations_
) {
580 waiting_for_navigation_
= false;
581 base::MessageLoopForUI::current()->Quit();
585 // This observer creates a list of loading tabs, and then waits for them all
586 // to stop loading and have the kInternetConnectedTitle.
588 // This is for the specific purpose of observing tabs time out after logging in
589 // to a captive portal, which will then cause them to reload.
590 // MultiNavigationObserver is insufficient for this because there may or may not
591 // be a LOAD_STOP event between the timeout and the reload.
592 // See bug http://crbug.com/133227
593 class FailLoadsAfterLoginObserver
: public content::NotificationObserver
{
595 FailLoadsAfterLoginObserver();
596 virtual ~FailLoadsAfterLoginObserver();
598 void WaitForNavigations();
601 typedef std::set
<const WebContents
*> TabSet
;
603 // content::NotificationObserver:
604 virtual void Observe(int type
, const content::NotificationSource
& source
,
605 const content::NotificationDetails
& details
) OVERRIDE
;
607 // The set of tabs that need to be navigated. This is the set of loading
608 // tabs when the observer is created.
609 TabSet tabs_needing_navigation_
;
611 // Number of tabs that have stopped navigating with the expected title. These
612 // are expected not to be navigated again.
613 TabSet tabs_navigated_to_final_destination_
;
615 // True if WaitForNavigations has been called, until
616 // |tabs_navigated_to_final_destination_| equals |tabs_needing_navigation_|.
617 bool waiting_for_navigation_
;
619 content::NotificationRegistrar registrar_
;
621 DISALLOW_COPY_AND_ASSIGN(FailLoadsAfterLoginObserver
);
624 FailLoadsAfterLoginObserver::FailLoadsAfterLoginObserver()
625 : waiting_for_navigation_(false) {
626 registrar_
.Add(this, content::NOTIFICATION_LOAD_STOP
,
627 content::NotificationService::AllSources());
628 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
630 tabs_needing_navigation_
.insert(*it
);
634 FailLoadsAfterLoginObserver::~FailLoadsAfterLoginObserver() {
637 void FailLoadsAfterLoginObserver::WaitForNavigations() {
638 // Shouldn't already be waiting for navigations.
639 EXPECT_FALSE(waiting_for_navigation_
);
640 if (tabs_needing_navigation_
.size() !=
641 tabs_navigated_to_final_destination_
.size()) {
642 waiting_for_navigation_
= true;
643 content::RunMessageLoop();
644 EXPECT_FALSE(waiting_for_navigation_
);
646 EXPECT_EQ(tabs_needing_navigation_
.size(),
647 tabs_navigated_to_final_destination_
.size());
650 void FailLoadsAfterLoginObserver::Observe(
652 const content::NotificationSource
& source
,
653 const content::NotificationDetails
& details
) {
654 ASSERT_EQ(type
, content::NOTIFICATION_LOAD_STOP
);
655 content::NavigationController
* controller
=
656 content::Source
<content::NavigationController
>(source
).ptr();
657 WebContents
* contents
= controller
->GetWebContents();
659 ASSERT_EQ(1u, tabs_needing_navigation_
.count(contents
));
660 ASSERT_EQ(0u, tabs_navigated_to_final_destination_
.count(contents
));
662 if (contents
->GetTitle() != base::ASCIIToUTF16(kInternetConnectedTitle
))
664 tabs_navigated_to_final_destination_
.insert(contents
);
666 if (waiting_for_navigation_
&&
667 tabs_needing_navigation_
.size() ==
668 tabs_navigated_to_final_destination_
.size()) {
669 waiting_for_navigation_
= false;
670 base::MessageLoopForUI::current()->Quit();
674 // An observer for watching the CaptivePortalService. It tracks the last
675 // received result and the total number of received results.
676 class CaptivePortalObserver
: public content::NotificationObserver
{
678 explicit CaptivePortalObserver(Profile
* profile
);
680 // Runs the message loop until until at exactly |update_count| capitive portal
681 // results have been received, since this creation of |this|. Expects no
682 // additional captive portal results.
683 void WaitForResults(int num_results_to_wait_for
);
685 int num_results_received() const { return num_results_received_
; }
687 CaptivePortalResult
captive_portal_result() const {
688 return captive_portal_result_
;
692 // Records results and exits the message loop, if needed.
693 virtual void Observe(int type
,
694 const content::NotificationSource
& source
,
695 const content::NotificationDetails
& details
) OVERRIDE
;
697 // Number of times OnPortalResult has been called since construction.
698 int num_results_received_
;
700 // If WaitForResults was called, the total number of updates for which to
701 // wait. Value doesn't matter when |waiting_for_result_| is false.
702 int num_results_to_wait_for_
;
704 bool waiting_for_result_
;
708 CaptivePortalService
* captive_portal_service_
;
710 // Last result received.
711 CaptivePortalResult captive_portal_result_
;
713 content::NotificationRegistrar registrar_
;
715 DISALLOW_COPY_AND_ASSIGN(CaptivePortalObserver
);
718 CaptivePortalObserver::CaptivePortalObserver(Profile
* profile
)
719 : num_results_received_(0),
720 num_results_to_wait_for_(0),
721 waiting_for_result_(false),
723 captive_portal_service_(
724 CaptivePortalServiceFactory::GetForProfile(profile
)),
725 captive_portal_result_(
726 captive_portal_service_
->last_detection_result()) {
728 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
,
729 content::Source
<Profile
>(profile_
));
732 void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for
) {
733 EXPECT_LT(0, num_results_to_wait_for
);
734 EXPECT_FALSE(waiting_for_result_
);
735 if (num_results_received_
< num_results_to_wait_for
) {
736 num_results_to_wait_for_
= num_results_to_wait_for
;
737 waiting_for_result_
= true;
738 content::RunMessageLoop();
739 EXPECT_FALSE(waiting_for_result_
);
741 EXPECT_EQ(num_results_to_wait_for
, num_results_received_
);
744 void CaptivePortalObserver::Observe(
746 const content::NotificationSource
& source
,
747 const content::NotificationDetails
& details
) {
748 ASSERT_EQ(type
, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
);
749 ASSERT_EQ(profile_
, content::Source
<Profile
>(source
).ptr());
751 CaptivePortalService::Results
* results
=
752 content::Details
<CaptivePortalService::Results
>(details
).ptr();
754 EXPECT_EQ(captive_portal_result_
, results
->previous_result
);
755 EXPECT_EQ(captive_portal_service_
->last_detection_result(),
758 captive_portal_result_
= results
->result
;
759 ++num_results_received_
;
761 if (waiting_for_result_
&&
762 num_results_to_wait_for_
== num_results_received_
) {
763 waiting_for_result_
= false;
764 base::MessageLoop::current()->Quit();
768 // Adds an HSTS rule for |host|, so that all HTTP requests sent to it will
769 // be switched to HTTPS requests.
770 void AddHstsHost(net::URLRequestContextGetter
* context_getter
,
771 const std::string
& host
) {
772 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO
));
773 net::TransportSecurityState
* transport_security_state
=
774 context_getter
->GetURLRequestContext()->transport_security_state();
775 if (!transport_security_state
) {
780 base::Time expiry
= base::Time::Now() + base::TimeDelta::FromDays(1000);
781 bool include_subdomains
= false;
782 transport_security_state
->AddHSTS(host
, expiry
, include_subdomains
);
787 class CaptivePortalBrowserTest
: public InProcessBrowserTest
{
789 CaptivePortalBrowserTest();
791 // InProcessBrowserTest:
792 virtual void SetUpOnMainThread() OVERRIDE
;
793 virtual void CleanUpOnMainThread() OVERRIDE
;
795 // Sets the captive portal checking preference. Does not affect the command
796 // line flag, which is set in SetUpCommandLine.
797 void EnableCaptivePortalDetection(Profile
* profile
, bool enabled
);
799 // Sets up the captive portal service for the given profile so that
800 // all checks go to |test_url|. Also disables all timers.
801 void SetUpCaptivePortalService(Profile
* profile
, const GURL
& test_url
);
803 // Returns true if |browser|'s profile is currently running a captive portal
805 bool CheckPending(Browser
* browser
);
807 // Returns the CaptivePortalTabReloader::State of |web_contents|.
808 CaptivePortalTabReloader::State
GetStateOfTabReloader(
809 WebContents
* web_contents
) const;
811 // Returns the CaptivePortalTabReloader::State of the indicated tab.
812 CaptivePortalTabReloader::State
GetStateOfTabReloaderAt(Browser
* browser
,
815 // Returns the number of tabs with the given state, across all profiles.
816 int NumTabsWithState(CaptivePortalTabReloader::State state
) const;
818 // Returns the number of tabs broken by captive portals, across all profiles.
819 int NumBrokenTabs() const;
821 // Returns the number of tabs that need to be reloaded due to having logged
822 // in to a captive portal, across all profiles.
823 int NumNeedReloadTabs() const;
825 // Navigates |browser|'s active tab to |url| and expects no captive portal
826 // test to be triggered. |expected_navigations| is the number of times the
827 // active tab will end up being navigated. It should be 1, except for the
828 // Link Doctor page, which acts like two navigations.
829 void NavigateToPageExpectNoTest(Browser
* browser
,
831 int expected_navigations
);
833 // Navigates |browser|'s active tab to an SSL tab that takes a while to load,
834 // triggering a captive portal check, which is expected to give the result
835 // |expected_result|. The page finishes loading, with a timeout, after the
836 // captive portal check.
837 void SlowLoadNoCaptivePortal(Browser
* browser
,
838 CaptivePortalResult 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
,
844 CaptivePortalResult expected_result
);
846 // Navigates the active tab to a slow loading SSL page, which will then
847 // trigger a captive portal test. The test is expected to find a captive
848 // portal. The slow loading page will continue to load after the function
849 // returns, until URLRequestTimeoutOnDemandJob::FailJobs() is called,
850 // at which point it will timeout.
852 // When |expect_login_tab| is false, no login tab is expected to be opened,
853 // because one already exists, and the function returns once the captive
854 // portal test is complete.
856 // If |expect_login_tab| is true, a login tab is then expected to be opened.
857 // It waits until both the login tab has finished loading, and two captive
858 // portal tests complete. The second test is triggered by the load of the
859 // captive portal tab completing.
861 // This function must not be called when the active tab is currently loading.
862 // Waits for the hanging request to be issued, so other functions can rely
863 // on URLRequestTimeoutOnDemandJob::WaitForJobs having been called.
864 void SlowLoadBehindCaptivePortal(Browser
* browser
, bool expect_login_tab
);
866 // Same as above, but takes extra parameters.
868 // |hanging_url| should either be kMockHttpsUrl or redirect to kMockHttpsUrl.
870 // |expected_portal_checks| and |expected_login_tab_navigations| allow
871 // client-side redirects to be tested. |expected_login_tab_navigations| is
872 // ignored when |expect_open_login_tab| is false.
873 void SlowLoadBehindCaptivePortal(Browser
* browser
,
874 bool expect_open_login_tab
,
875 const GURL
& hanging_url
,
876 int expected_portal_checks
,
877 int expected_login_tab_navigations
);
879 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has
880 // a connection timeout rather having its time trigger, and the function
881 // waits until that timeout occurs.
882 void FastTimeoutBehindCaptivePortal(Browser
* browser
,
883 bool expect_open_login_tab
);
885 // Much as above, but accepts a URL parameter and can be used for errors that
886 // trigger captive portal checks other than timeouts. |error_url| should
887 // result in an error rather than hanging.
888 void FastErrorBehindCaptivePortal(Browser
* browser
,
889 bool expect_open_login_tab
,
890 const GURL
& error_url
);
892 // Navigates the login tab without logging in. The login tab must be the
893 // specified browser's active tab. Expects no other tab to change state.
894 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
895 // that nothing has gone wrong prior to the function call.
896 void NavigateLoginTab(Browser
* browser
,
897 int num_loading_tabs
,
898 int num_timed_out_tabs
);
900 // Simulates a login by updating the URLRequestMockCaptivePortalJob's
901 // behind captive portal state, and navigating the login tab. Waits for
902 // all broken but not loading tabs to be reloaded.
903 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
904 // that nothing has gone wrong prior to the function call.
905 void Login(Browser
* browser
, int num_loading_tabs
, int num_timed_out_tabs
);
907 // Makes the slow SSL loads of all active tabs time out at once, and waits for
908 // them to finish both that load and the automatic reload it should trigger.
909 // There should be no timed out tabs when this is called.
910 void FailLoadsAfterLogin(Browser
* browser
, int num_loading_tabs
);
912 // Makes the slow SSL loads of all active tabs time out at once, and waits for
913 // them to finish displaying their error pages. The login tab should be the
914 // active tab. There should be no timed out tabs when this is called.
915 void FailLoadsWithoutLogin(Browser
* browser
, int num_loading_tabs
);
917 // Navigates |browser|'s active tab to |starting_url| while not behind a
918 // captive portal. Then navigates to |interrupted_url|, which should create
919 // a URLRequestTimeoutOnDemandJob, which is then abandoned. The load should
920 // trigger a captive portal check, which finds a captive portal and opens a
923 // Then the navigation is interrupted by a navigation to |timeout_url|, which
924 // should trigger a captive portal check, and finally the test simulates
927 // The purpose of this test is to make sure the TabHelper triggers a captive
928 // portal check when a load is interrupted by another load, particularly in
929 // the case of cross-process navigations.
930 void RunNavigateLoadingTabToTimeoutTest(Browser
* browser
,
931 const GURL
& starting_url
,
932 const GURL
& interrupted_url
,
933 const GURL
& timeout_url
);
935 // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads
936 // before a captive portal check.
937 void SetSlowSSLLoadTime(CaptivePortalTabReloader
* tab_reloader
,
938 base::TimeDelta slow_ssl_load_time
);
940 CaptivePortalTabReloader
* GetTabReloader(WebContents
* web_contents
) const;
943 DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest
);
946 CaptivePortalBrowserTest::CaptivePortalBrowserTest() {
949 void CaptivePortalBrowserTest::SetUpOnMainThread() {
950 // Enable mock requests.
951 content::BrowserThread::PostTask(
952 content::BrowserThread::IO
, FROM_HERE
,
953 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled
, true));
954 URLRequestMockCaptivePortalJobFactory::AddUrlHandlers();
956 // Double-check that the captive portal service isn't enabled by default for
958 EXPECT_EQ(CaptivePortalService::DISABLED_FOR_TESTING
,
959 CaptivePortalService::get_state_for_testing());
961 CaptivePortalService::set_state_for_testing(
962 CaptivePortalService::SKIP_OS_CHECK_FOR_TESTING
);
963 EnableCaptivePortalDetection(browser()->profile(), true);
965 // Set the captive portal service to use URLRequestMockCaptivePortalJob's
966 // mock URL, by default.
967 SetUpCaptivePortalService(browser()->profile(),
968 GURL(kMockCaptivePortalTestUrl
));
971 void CaptivePortalBrowserTest::CleanUpOnMainThread() {
972 // No test should have a captive portal check pending on quit.
973 EXPECT_FALSE(CheckPending(browser()));
976 void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
977 Profile
* profile
, bool enabled
) {
978 profile
->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled
, enabled
);
981 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile
* profile
,
982 const GURL
& test_url
) {
983 CaptivePortalService
* captive_portal_service
=
984 CaptivePortalServiceFactory::GetForProfile(profile
);
985 captive_portal_service
->set_test_url(test_url
);
987 // Don't use any non-zero timers. Timers are checked in unit tests.
988 CaptivePortalService::RecheckPolicy
* recheck_policy
=
989 &captive_portal_service
->recheck_policy();
990 recheck_policy
->initial_backoff_no_portal_ms
= 0;
991 recheck_policy
->initial_backoff_portal_ms
= 0;
992 recheck_policy
->backoff_policy
.maximum_backoff_ms
= 0;
995 bool CaptivePortalBrowserTest::CheckPending(Browser
* browser
) {
996 CaptivePortalService
* captive_portal_service
=
997 CaptivePortalServiceFactory::GetForProfile(browser
->profile());
999 return captive_portal_service
->DetectionInProgress() ||
1000 captive_portal_service
->TimerRunning();
1003 CaptivePortalTabReloader::State
CaptivePortalBrowserTest::GetStateOfTabReloader(
1004 WebContents
* web_contents
) const {
1005 return GetTabReloader(web_contents
)->state();
1008 CaptivePortalTabReloader::State
1009 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(Browser
* browser
,
1011 return GetStateOfTabReloader(
1012 browser
->tab_strip_model()->GetWebContentsAt(index
));
1015 int CaptivePortalBrowserTest::NumTabsWithState(
1016 CaptivePortalTabReloader::State state
) const {
1018 for (TabContentsIterator it
; !it
.done(); it
.Next()) {
1019 if (GetStateOfTabReloader(*it
) == state
)
1025 int CaptivePortalBrowserTest::NumBrokenTabs() const {
1026 return NumTabsWithState(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
);
1029 int CaptivePortalBrowserTest::NumNeedReloadTabs() const {
1030 return NumTabsWithState(CaptivePortalTabReloader::STATE_NEEDS_RELOAD
);
1033 void CaptivePortalBrowserTest::NavigateToPageExpectNoTest(
1036 int expected_navigations
) {
1037 MultiNavigationObserver navigation_observer
;
1038 CaptivePortalObserver
portal_observer(browser
->profile());
1040 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
1041 browser
, url
, expected_navigations
);
1043 // No captive portal checks should have ocurred or be pending, and there
1044 // should be no new tabs.
1045 EXPECT_EQ(0, portal_observer
.num_results_received());
1046 EXPECT_FALSE(CheckPending(browser
));
1047 EXPECT_EQ(1, browser
->tab_strip_model()->count());
1048 EXPECT_EQ(expected_navigations
, navigation_observer
.num_navigations());
1049 EXPECT_EQ(0, NumLoadingTabs());
1050 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1051 GetStateOfTabReloaderAt(browser
, 0));
1054 void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal(
1056 CaptivePortalResult expected_result
) {
1057 CaptivePortalTabReloader
* tab_reloader
=
1058 GetTabReloader(browser
->tab_strip_model()->GetActiveWebContents());
1059 ASSERT_TRUE(tab_reloader
);
1060 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
1062 MultiNavigationObserver navigation_observer
;
1063 CaptivePortalObserver
portal_observer(browser
->profile());
1064 ui_test_utils::NavigateToURLWithDisposition(browser
,
1065 GURL(kMockHttpsUrl
),
1067 ui_test_utils::BROWSER_TEST_NONE
);
1069 portal_observer
.WaitForResults(1);
1071 ASSERT_EQ(1, browser
->tab_strip_model()->count());
1072 EXPECT_EQ(expected_result
, portal_observer
.captive_portal_result());
1073 EXPECT_EQ(1, portal_observer
.num_results_received());
1074 EXPECT_EQ(0, navigation_observer
.num_navigations());
1075 EXPECT_FALSE(CheckPending(browser
));
1077 // First tab should still be loading.
1078 EXPECT_EQ(1, NumLoadingTabs());
1080 // Wait for the request to be issued, then time it out.
1081 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1082 URLRequestTimeoutOnDemandJob::FailJobs(1);
1083 navigation_observer
.WaitForNavigations(1);
1085 ASSERT_EQ(1, browser
->tab_strip_model()->count());
1086 EXPECT_EQ(1, portal_observer
.num_results_received());
1087 EXPECT_FALSE(CheckPending(browser
));
1088 EXPECT_EQ(0, NumLoadingTabs());
1090 // Set a slow SSL load time to prevent the timer from triggering.
1091 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
1094 void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal(
1096 CaptivePortalResult expected_result
) {
1097 ASSERT_NE(expected_result
, captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
1099 // Set the load time to be large, so the timer won't trigger. The value is
1100 // not restored at the end of the function.
1101 CaptivePortalTabReloader
* tab_reloader
=
1102 GetTabReloader(browser
->tab_strip_model()->GetActiveWebContents());
1103 ASSERT_TRUE(tab_reloader
);
1104 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromHours(1));
1106 MultiNavigationObserver navigation_observer
;
1107 CaptivePortalObserver
portal_observer(browser
->profile());
1109 // Neither of these should be changed by the navigation.
1110 int active_index
= browser
->tab_strip_model()->active_index();
1111 int expected_tab_count
= browser
->tab_strip_model()->count();
1113 ui_test_utils::NavigateToURL(
1115 URLRequestFailedJob::GetMockHttpsUrl(net::ERR_CONNECTION_TIMED_OUT
));
1117 // An attempt to detect a captive portal should have started by now. If not,
1118 // abort early to prevent hanging.
1119 ASSERT_TRUE(portal_observer
.num_results_received() > 0 ||
1120 CheckPending(browser
));
1122 portal_observer
.WaitForResults(1);
1123 navigation_observer
.WaitForNavigations(1);
1125 // Check the result.
1126 EXPECT_EQ(1, portal_observer
.num_results_received());
1127 EXPECT_EQ(expected_result
, portal_observer
.captive_portal_result());
1129 // Check that the right tab was navigated, and there were no extra
1131 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1132 browser
->tab_strip_model()->GetWebContentsAt(active_index
)));
1133 EXPECT_EQ(0, NumLoadingTabs());
1135 // Check the tab's state, and verify no captive portal check is pending.
1136 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1137 GetStateOfTabReloaderAt(browser
, 0));
1138 EXPECT_FALSE(CheckPending(browser
));
1140 // Make sure no login tab was opened.
1141 EXPECT_EQ(expected_tab_count
, browser
->tab_strip_model()->count());
1144 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
1146 bool expect_open_login_tab
) {
1147 SlowLoadBehindCaptivePortal(browser
,
1148 expect_open_login_tab
,
1149 GURL(kMockHttpsUrl
),
1154 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
1156 bool expect_open_login_tab
,
1157 const GURL
& hanging_url
,
1158 int expected_portal_checks
,
1159 int expected_login_tab_navigations
) {
1160 ASSERT_GE(expected_portal_checks
, 1);
1161 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1162 // Calling this on a tab that's waiting for a load to manually be timed out
1163 // will result in a hang.
1164 ASSERT_FALSE(tab_strip_model
->GetActiveWebContents()->IsLoading());
1166 // Trigger a captive portal check quickly.
1167 CaptivePortalTabReloader
* tab_reloader
=
1168 GetTabReloader(tab_strip_model
->GetActiveWebContents());
1169 ASSERT_TRUE(tab_reloader
);
1170 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
1172 // Number of tabs expected to be open after the captive portal checks
1174 int initial_tab_count
= tab_strip_model
->count();
1175 int initial_active_index
= tab_strip_model
->active_index();
1176 int initial_loading_tabs
= NumLoadingTabs();
1177 int expected_broken_tabs
= NumBrokenTabs();
1178 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
!=
1179 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents())) {
1180 ++expected_broken_tabs
;
1183 MultiNavigationObserver navigation_observer
;
1184 CaptivePortalObserver
portal_observer(browser
->profile());
1185 ui_test_utils::NavigateToURLWithDisposition(browser
,
1188 ui_test_utils::BROWSER_TEST_NONE
);
1189 portal_observer
.WaitForResults(expected_portal_checks
);
1191 if (expect_open_login_tab
) {
1192 ASSERT_GE(expected_login_tab_navigations
, 1);
1194 navigation_observer
.WaitForNavigations(expected_login_tab_navigations
);
1196 ASSERT_EQ(initial_tab_count
+ 1, tab_strip_model
->count());
1197 EXPECT_EQ(initial_tab_count
, tab_strip_model
->active_index());
1199 EXPECT_EQ(expected_login_tab_navigations
,
1200 navigation_observer
.NumNavigationsForTab(
1201 tab_strip_model
->GetWebContentsAt(initial_tab_count
)));
1202 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1203 GetStateOfTabReloaderAt(browser
, 1));
1204 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1206 EXPECT_EQ(0, navigation_observer
.num_navigations());
1207 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1208 ASSERT_EQ(initial_tab_count
, tab_strip_model
->count());
1209 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1212 // Wait for all the expect resource loads to actually start, so subsequent
1213 // functions can rely on them having started.
1214 URLRequestTimeoutOnDemandJob::WaitForJobs(initial_loading_tabs
+ 1);
1216 EXPECT_EQ(initial_loading_tabs
+ 1, NumLoadingTabs());
1217 EXPECT_EQ(expected_broken_tabs
, NumBrokenTabs());
1218 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
1219 portal_observer
.captive_portal_result());
1220 EXPECT_EQ(expected_portal_checks
, portal_observer
.num_results_received());
1221 EXPECT_FALSE(CheckPending(browser
));
1223 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1224 GetStateOfTabReloaderAt(browser
, initial_active_index
));
1226 // Reset the load time to be large, so the timer won't trigger on a reload.
1227 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromHours(1));
1230 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
1232 bool expect_open_login_tab
) {
1233 FastErrorBehindCaptivePortal(browser
,
1234 expect_open_login_tab
,
1235 GURL(kMockHttpsQuickTimeoutUrl
));
1238 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
1240 bool expect_open_login_tab
,
1241 const GURL
& error_url
) {
1242 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1243 // Calling this on a tab that's waiting for a load to manually be timed out
1244 // will result in a hang.
1245 ASSERT_FALSE(tab_strip_model
->GetActiveWebContents()->IsLoading());
1247 // Set the load time to be large, so the timer won't trigger. The value is
1248 // not restored at the end of the function.
1249 CaptivePortalTabReloader
* tab_reloader
=
1250 GetTabReloader(tab_strip_model
->GetActiveWebContents());
1251 ASSERT_TRUE(tab_reloader
);
1252 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromHours(1));
1254 // Number of tabs expected to be open after the captive portal checks
1256 int initial_tab_count
= tab_strip_model
->count();
1257 int initial_active_index
= tab_strip_model
->active_index();
1258 int initial_loading_tabs
= NumLoadingTabs();
1259 int expected_broken_tabs
= NumBrokenTabs();
1260 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
!=
1261 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents())) {
1262 ++expected_broken_tabs
;
1265 MultiNavigationObserver navigation_observer
;
1266 CaptivePortalObserver
portal_observer(browser
->profile());
1267 ui_test_utils::NavigateToURLWithDisposition(browser
,
1270 ui_test_utils::BROWSER_TEST_NONE
);
1271 portal_observer
.WaitForResults(1);
1273 if (expect_open_login_tab
) {
1274 navigation_observer
.WaitForNavigations(2);
1275 ASSERT_EQ(initial_tab_count
+ 1, tab_strip_model
->count());
1276 EXPECT_EQ(initial_tab_count
, tab_strip_model
->active_index());
1277 // Make sure that the originally active tab and the captive portal tab have
1278 // each loaded once.
1279 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1280 tab_strip_model
->GetWebContentsAt(initial_active_index
)));
1281 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1282 tab_strip_model
->GetWebContentsAt(initial_tab_count
)));
1283 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1284 GetStateOfTabReloaderAt(browser
, 1));
1285 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1287 navigation_observer
.WaitForNavigations(1);
1288 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1289 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1290 tab_strip_model
->GetWebContentsAt(initial_active_index
)));
1291 ASSERT_EQ(initial_tab_count
, tab_strip_model
->count());
1292 EXPECT_EQ(initial_active_index
, tab_strip_model
->active_index());
1295 EXPECT_EQ(initial_loading_tabs
, NumLoadingTabs());
1296 EXPECT_EQ(expected_broken_tabs
, NumBrokenTabs());
1297 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
1298 portal_observer
.captive_portal_result());
1299 EXPECT_EQ(1, portal_observer
.num_results_received());
1300 EXPECT_FALSE(CheckPending(browser
));
1302 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1303 GetStateOfTabReloaderAt(browser
, initial_active_index
));
1306 void CaptivePortalBrowserTest::NavigateLoginTab(Browser
* browser
,
1307 int num_loading_tabs
,
1308 int num_timed_out_tabs
) {
1309 MultiNavigationObserver navigation_observer
;
1310 CaptivePortalObserver
portal_observer(browser
->profile());
1312 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1313 int initial_tab_count
= tab_strip_model
->count();
1314 EXPECT_EQ(num_loading_tabs
, NumLoadingTabs());
1315 EXPECT_EQ(num_timed_out_tabs
, NumBrokenTabs() - NumLoadingTabs());
1317 int login_tab_index
= tab_strip_model
->active_index();
1318 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1319 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents()));
1320 ASSERT_TRUE(IsLoginTab(browser
->tab_strip_model()->GetActiveWebContents()));
1322 // Do the navigation.
1323 content::RenderFrameHost
* render_frame_host
=
1324 tab_strip_model
->GetActiveWebContents()->GetMainFrame();
1325 render_frame_host
->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
1327 portal_observer
.WaitForResults(1);
1328 navigation_observer
.WaitForNavigations(1);
1330 // Check the captive portal result.
1331 EXPECT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
1332 portal_observer
.captive_portal_result());
1333 EXPECT_EQ(1, portal_observer
.num_results_received());
1334 EXPECT_FALSE(CheckPending(browser
));
1336 // Make sure not much has changed.
1337 EXPECT_EQ(initial_tab_count
, tab_strip_model
->count());
1338 EXPECT_EQ(num_loading_tabs
, NumLoadingTabs());
1339 EXPECT_EQ(num_loading_tabs
+ num_timed_out_tabs
, NumBrokenTabs());
1340 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1341 GetStateOfTabReloaderAt(browser
, login_tab_index
));
1342 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1344 // Make sure there were no unexpected navigations.
1345 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1346 tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1349 void CaptivePortalBrowserTest::Login(Browser
* browser
,
1350 int num_loading_tabs
,
1351 int num_timed_out_tabs
) {
1352 // Simulate logging in.
1353 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1355 MultiNavigationObserver navigation_observer
;
1356 CaptivePortalObserver
portal_observer(browser
->profile());
1358 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1359 int initial_tab_count
= tab_strip_model
->count();
1360 ASSERT_EQ(num_loading_tabs
, NumLoadingTabs());
1361 EXPECT_EQ(num_timed_out_tabs
, NumBrokenTabs() - NumLoadingTabs());
1363 // Verify that the login page is on top.
1364 int login_tab_index
= tab_strip_model
->active_index();
1365 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1366 GetStateOfTabReloaderAt(browser
, login_tab_index
));
1367 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1369 // Trigger a navigation.
1370 content::RenderFrameHost
* render_frame_host
=
1371 tab_strip_model
->GetActiveWebContents()->GetMainFrame();
1372 render_frame_host
->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
1374 portal_observer
.WaitForResults(1);
1376 // Wait for all the timed out tabs to reload.
1377 navigation_observer
.WaitForNavigations(1 + num_timed_out_tabs
);
1378 EXPECT_EQ(1, portal_observer
.num_results_received());
1380 // The tabs that were loading before should still be loading, and now be in
1381 // STATE_NEEDS_RELOAD.
1382 EXPECT_EQ(0, NumBrokenTabs());
1383 EXPECT_EQ(num_loading_tabs
, NumLoadingTabs());
1384 EXPECT_EQ(num_loading_tabs
, NumNeedReloadTabs());
1386 // Make sure that the broken tabs have reloaded, and there's no more
1387 // captive portal tab.
1388 EXPECT_EQ(initial_tab_count
, tab_strip_model
->count());
1389 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1390 GetStateOfTabReloaderAt(browser
, login_tab_index
));
1391 EXPECT_FALSE(IsLoginTab(tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1393 // Make sure there were no unexpected navigations of the login tab.
1394 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1395 tab_strip_model
->GetWebContentsAt(login_tab_index
)));
1398 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser
* browser
,
1399 int num_loading_tabs
) {
1400 ASSERT_EQ(num_loading_tabs
, NumLoadingTabs());
1401 ASSERT_EQ(num_loading_tabs
, NumNeedReloadTabs());
1402 EXPECT_EQ(0, NumBrokenTabs());
1404 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1405 int initial_num_tabs
= tab_strip_model
->count();
1406 int initial_active_tab
= tab_strip_model
->active_index();
1408 CaptivePortalObserver
portal_observer(browser
->profile());
1409 FailLoadsAfterLoginObserver fail_loads_observer
;
1410 // Connection(s) finally time out. There should have already been a call
1411 // to wait for the requests to be issued before logging on.
1412 URLRequestTimeoutOnDemandJob::WaitForJobs(num_loading_tabs
);
1413 URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs
);
1415 fail_loads_observer
.WaitForNavigations();
1417 // No captive portal checks should have ocurred or be pending, and there
1418 // should be no new tabs.
1419 EXPECT_EQ(0, portal_observer
.num_results_received());
1420 EXPECT_FALSE(CheckPending(browser
));
1421 EXPECT_EQ(initial_num_tabs
, tab_strip_model
->count());
1423 EXPECT_EQ(initial_active_tab
, tab_strip_model
->active_index());
1425 EXPECT_EQ(0, NumNeedReloadTabs());
1426 EXPECT_EQ(0, NumLoadingTabs());
1429 void CaptivePortalBrowserTest::FailLoadsWithoutLogin(Browser
* browser
,
1430 int num_loading_tabs
) {
1431 ASSERT_EQ(num_loading_tabs
, NumLoadingTabs());
1432 ASSERT_EQ(0, NumNeedReloadTabs());
1433 EXPECT_EQ(num_loading_tabs
, NumBrokenTabs());
1435 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1436 int initial_num_tabs
= tab_strip_model
->count();
1437 int login_tab
= tab_strip_model
->active_index();
1438 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1439 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents()));
1440 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetActiveWebContents()));
1442 CaptivePortalObserver
portal_observer(browser
->profile());
1443 MultiNavigationObserver navigation_observer
;
1444 // Connection(s) finally time out. There should have already been a call
1445 // to wait for the requests to be issued.
1446 URLRequestTimeoutOnDemandJob::FailJobs(num_loading_tabs
);
1448 navigation_observer
.WaitForNavigations(num_loading_tabs
);
1450 // No captive portal checks should have ocurred or be pending, and there
1451 // should be no new tabs.
1452 EXPECT_EQ(0, portal_observer
.num_results_received());
1453 EXPECT_FALSE(CheckPending(browser
));
1454 EXPECT_EQ(initial_num_tabs
, tab_strip_model
->count());
1456 EXPECT_EQ(0, NumNeedReloadTabs());
1457 EXPECT_EQ(0, NumLoadingTabs());
1458 EXPECT_EQ(num_loading_tabs
, NumBrokenTabs());
1459 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1460 GetStateOfTabReloader(tab_strip_model
->GetActiveWebContents()));
1461 EXPECT_TRUE(IsLoginTab(tab_strip_model
->GetActiveWebContents()));
1462 EXPECT_EQ(login_tab
, tab_strip_model
->active_index());
1464 EXPECT_EQ(0, navigation_observer
.NumNavigationsForTab(
1465 tab_strip_model
->GetWebContentsAt(login_tab
)));
1468 void CaptivePortalBrowserTest::RunNavigateLoadingTabToTimeoutTest(
1470 const GURL
& starting_url
,
1471 const GURL
& hanging_url
,
1472 const GURL
& timeout_url
) {
1473 // Temporarily disable the captive portal and navigate to the starting
1474 // URL, which may be a URL that will hang when behind a captive portal.
1475 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1476 NavigateToPageExpectNoTest(browser
, starting_url
, 1);
1477 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
1479 // Go to the first hanging url.
1480 SlowLoadBehindCaptivePortal(browser
, true, hanging_url
, 1, 1);
1482 // Abandon the request.
1483 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1484 URLRequestTimeoutOnDemandJob::AbandonJobs(1);
1486 TabStripModel
* tab_strip_model
= browser
->tab_strip_model();
1487 CaptivePortalTabReloader
* tab_reloader
=
1488 GetTabReloader(tab_strip_model
->GetWebContentsAt(0));
1489 ASSERT_TRUE(tab_reloader
);
1491 // A non-zero delay makes it more likely that CaptivePortalTabHelper will
1492 // be confused by events relating to canceling the old navigation.
1493 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromSeconds(2));
1494 CaptivePortalObserver
portal_observer(browser
->profile());
1496 // Navigate the error tab to another slow loading page. Can't have
1497 // ui_test_utils do the navigation because it will wait for loading tabs to
1498 // stop loading before navigating.
1500 // This may result in either 0 or 1 DidStopLoading events. If there is one,
1501 // it must happen before the CaptivePortalService sends out its test request,
1502 // so waiting for PortalObserver to see that request prevents it from
1503 // confusing the MultiNavigationObservers used later.
1504 tab_strip_model
->ActivateTabAt(0, true);
1505 browser
->OpenURL(content::OpenURLParams(timeout_url
,
1506 content::Referrer(),
1508 content::PAGE_TRANSITION_TYPED
,
1510 portal_observer
.WaitForResults(1);
1511 EXPECT_FALSE(CheckPending(browser
));
1512 EXPECT_EQ(1, NumLoadingTabs());
1513 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1514 GetStateOfTabReloaderAt(browser
, 0));
1515 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1516 GetStateOfTabReloaderAt(browser
, 1));
1517 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1519 // Need to make sure the request has been issued before logging in.
1520 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1522 // Simulate logging in.
1523 tab_strip_model
->ActivateTabAt(1, true);
1524 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
1525 Login(browser
, 1, 0);
1527 // Timeout occurs, and page is automatically reloaded.
1528 FailLoadsAfterLogin(browser
, 1);
1531 void CaptivePortalBrowserTest::SetSlowSSLLoadTime(
1532 CaptivePortalTabReloader
* tab_reloader
,
1533 base::TimeDelta slow_ssl_load_time
) {
1534 tab_reloader
->set_slow_ssl_load_time(slow_ssl_load_time
);
1537 CaptivePortalTabReloader
* CaptivePortalBrowserTest::GetTabReloader(
1538 WebContents
* web_contents
) const {
1539 return CaptivePortalTabHelper::FromWebContents(web_contents
)->
1540 GetTabReloaderForTest();
1543 // Make sure there's no test for a captive portal on HTTP timeouts. This will
1544 // also trigger the link doctor page, which results in the load of a second
1546 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpTimeout
) {
1547 GURL url
= URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT
);
1548 NavigateToPageExpectNoTest(browser(), url
, 2);
1551 // Make sure there's no check for a captive portal on HTTPS errors other than
1552 // timeouts, when they preempt the slow load timer.
1553 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpsNonTimeoutError
) {
1554 GURL url
= URLRequestFailedJob::GetMockHttpsUrl(net::ERR_UNEXPECTED
);
1555 NavigateToPageExpectNoTest(browser(), url
, 1);
1558 // Make sure no captive portal test triggers on HTTPS timeouts of iframes.
1559 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpsIframeTimeout
) {
1560 // Use an HTTPS server for the top level page.
1561 net::SpawnedTestServer
https_server(
1562 net::SpawnedTestServer::TYPE_HTTPS
, net::SpawnedTestServer::kLocalhost
,
1563 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1564 ASSERT_TRUE(https_server
.Start());
1566 GURL url
= https_server
.GetURL(kTestServerIframeTimeoutPath
);
1567 NavigateToPageExpectNoTest(browser(), url
, 1);
1570 // Check the captive portal result when the test request reports a network
1571 // error. The check is triggered by a slow loading page, and the page
1572 // errors out only after getting a captive portal result.
1573 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, RequestFails
) {
1574 SetUpCaptivePortalService(
1575 browser()->profile(),
1576 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED
));
1577 SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_NO_RESPONSE
);
1580 // Same as above, but for the rather unlikely case that the connection times out
1581 // before the timer triggers.
1582 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, RequestFailsFastTimout
) {
1583 SetUpCaptivePortalService(
1584 browser()->profile(),
1585 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED
));
1586 FastTimeoutNoCaptivePortal(browser(), captive_portal::RESULT_NO_RESPONSE
);
1589 // Checks the case that captive portal detection is disabled.
1590 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, Disabled
) {
1591 EnableCaptivePortalDetection(browser()->profile(), false);
1592 SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_INTERNET_CONNECTED
);
1595 // Checks that we look for a captive portal on HTTPS timeouts and don't reload
1596 // the error tab when the captive portal probe gets a 204 response, indicating
1597 // there is no captive portal.
1598 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, InternetConnected
) {
1599 // Can't just use SetBehindCaptivePortal(false), since then there wouldn't
1601 ASSERT_TRUE(test_server()->Start());
1602 SetUpCaptivePortalService(browser()->profile(),
1603 test_server()->GetURL("nocontent"));
1604 SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_INTERNET_CONNECTED
);
1607 // Checks that no login page is opened when the HTTP test URL redirects to an
1608 // SSL certificate error.
1609 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, RedirectSSLCertError
) {
1610 // Need an HTTP TestServer to handle a dynamically created server redirect.
1611 ASSERT_TRUE(test_server()->Start());
1613 net::SpawnedTestServer::SSLOptions ssl_options
;
1614 ssl_options
.server_certificate
=
1615 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME
;
1616 net::SpawnedTestServer
https_server(
1617 net::SpawnedTestServer::TYPE_HTTPS
, ssl_options
,
1618 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1619 ASSERT_TRUE(https_server
.Start());
1621 GURL ssl_login_url
= https_server
.GetURL(kTestServerLoginPath
);
1623 CaptivePortalService
* captive_portal_service
=
1624 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
1625 ASSERT_TRUE(captive_portal_service
);
1626 SetUpCaptivePortalService(
1627 browser()->profile(),
1628 test_server()->GetURL(CreateServerRedirect(ssl_login_url
.spec())));
1630 SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_NO_RESPONSE
);
1633 // A slow SSL load triggers a captive portal check. The user logs on before
1634 // the SSL page times out. We wait for the timeout and subsequent reload.
1635 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, Login
) {
1636 // Load starts, detect captive portal and open up a login tab.
1637 SlowLoadBehindCaptivePortal(browser(), true);
1639 // Log in. One loading tab, no timed out ones.
1640 Login(browser(), 1, 0);
1642 // Timeout occurs, and page is automatically reloaded.
1643 FailLoadsAfterLogin(browser(), 1);
1646 // Same as above, except we make sure everything works with an incognito
1647 // profile. Main issues it tests for are that the incognito has its own
1648 // non-NULL captive portal service, and we open the tab in the correct
1650 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginIncognito
) {
1651 // This will watch tabs for both profiles, but only used to make sure no
1652 // navigations occur for the non-incognito profile.
1653 MultiNavigationObserver navigation_observer
;
1654 CaptivePortalObserver
non_incognito_portal_observer(browser()->profile());
1656 Browser
* incognito_browser
= CreateIncognitoBrowser();
1657 EnableCaptivePortalDetection(incognito_browser
->profile(), true);
1658 SetUpCaptivePortalService(incognito_browser
->profile(),
1659 GURL(kMockCaptivePortalTestUrl
));
1661 SlowLoadBehindCaptivePortal(incognito_browser
, true);
1663 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1664 EXPECT_EQ(1, tab_strip_model
->count());
1665 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1666 GetStateOfTabReloaderAt(browser(), 0));
1668 Login(incognito_browser
, 1, 0);
1669 FailLoadsAfterLogin(incognito_browser
, 1);
1671 EXPECT_EQ(1, tab_strip_model
->count());
1672 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1673 GetStateOfTabReloaderAt(browser(), 0));
1675 EXPECT_EQ(0, navigation_observer
.NumNavigationsForTab(
1676 tab_strip_model
->GetWebContentsAt(0)));
1677 EXPECT_EQ(0, non_incognito_portal_observer
.num_results_received());
1680 // The captive portal page is opened before the SSL page times out,
1681 // but the user logs in only after the page times out.
1682 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginSlow
) {
1683 SlowLoadBehindCaptivePortal(browser(), true);
1684 FailLoadsWithoutLogin(browser(), 1);
1685 Login(browser(), 0, 1);
1688 // Checks the unlikely case that the tab times out before the timer triggers.
1689 // This most likely won't happen, but should still work:
1690 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginFastTimeout
) {
1691 FastTimeoutBehindCaptivePortal(browser(), true);
1692 Login(browser(), 0, 1);
1695 // A cert error triggers a captive portal check and results in opening a login
1696 // tab. The user then logs in and the page with the error is reloaded.
1697 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, SSLCertErrorLogin
) {
1698 // Need an HTTP TestServer to handle a dynamically created server redirect.
1699 ASSERT_TRUE(test_server()->Start());
1701 net::SpawnedTestServer::SSLOptions https_options
;
1702 https_options
.server_certificate
=
1703 net::SpawnedTestServer::SSLOptions::CERT_MISMATCHED_NAME
;
1704 net::SpawnedTestServer
https_server(
1705 net::SpawnedTestServer::TYPE_HTTPS
, https_options
,
1706 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1707 ASSERT_TRUE(https_server
.Start());
1709 // The path does not matter.
1710 GURL cert_error_url
= https_server
.GetURL(kTestServerLoginPath
);
1711 // The interstitial should trigger a captive portal check when it opens, just
1712 // like navigating to kMockHttpsQuickTimeoutUrl.
1713 FastErrorBehindCaptivePortal(browser(), true, cert_error_url
);
1715 // Simulate logging in. Can't use Login() because the interstitial tab looks
1716 // like a cross between a hung tab (Load was never committed) and a tab at an
1717 // error page (The load was stopped).
1718 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1719 MultiNavigationObserver navigation_observer
;
1720 CaptivePortalObserver
portal_observer(browser()->profile());
1722 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1723 content::RenderFrameHost
* render_frame_host
=
1724 tab_strip_model
->GetActiveWebContents()->GetMainFrame();
1725 render_frame_host
->ExecuteJavaScript(base::ASCIIToUTF16("submitForm()"));
1727 // The captive portal tab navigation will trigger a captive portal check,
1728 // and reloading the original tab will bring up the interstitial page again,
1729 // triggering a second captive portal check.
1730 portal_observer
.WaitForResults(2);
1732 // Wait for both tabs to finish loading.
1733 navigation_observer
.WaitForNavigations(2);
1734 EXPECT_EQ(2, portal_observer
.num_results_received());
1735 EXPECT_FALSE(CheckPending(browser()));
1736 EXPECT_EQ(captive_portal::RESULT_INTERNET_CONNECTED
,
1737 portal_observer
.captive_portal_result());
1739 // Check state of tabs. While the first tab is still displaying an
1740 // interstitial page, since no portal was found, it should be in STATE_NONE,
1741 // as should the login tab.
1742 ASSERT_EQ(2, tab_strip_model
->count());
1743 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1744 GetStateOfTabReloaderAt(browser(), 0));
1745 EXPECT_FALSE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1746 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1747 GetStateOfTabReloaderAt(browser(), 1));
1749 // Make sure only one navigation was for the login tab.
1750 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1751 tab_strip_model
->GetWebContentsAt(1)));
1754 // Tries navigating both the tab that encounters an SSL timeout and the
1755 // login tab twice, only logging in the second time.
1756 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, LoginExtraNavigations
) {
1757 FastTimeoutBehindCaptivePortal(browser(), true);
1759 // Activate the timed out tab and navigate it to a timeout again.
1760 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1761 tab_strip_model
->ActivateTabAt(0, true);
1762 FastTimeoutBehindCaptivePortal(browser(), false);
1764 // Activate and navigate the captive portal tab. This should not trigger a
1765 // reload of the tab with the error.
1766 tab_strip_model
->ActivateTabAt(1, true);
1767 NavigateLoginTab(browser(), 0, 1);
1769 // Simulate logging in.
1770 Login(browser(), 0, 1);
1773 // After the first SSL timeout, closes the login tab and makes sure it's opened
1774 // it again on a second timeout.
1775 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, CloseLoginTab
) {
1776 // First load starts, opens a login tab, and then times out.
1777 SlowLoadBehindCaptivePortal(browser(), true);
1778 FailLoadsWithoutLogin(browser(), 1);
1781 chrome::CloseTab(browser());
1783 // Go through the standard slow load login, and make sure it still works.
1784 SlowLoadBehindCaptivePortal(browser(), true);
1785 Login(browser(), 1, 0);
1786 FailLoadsAfterLogin(browser(), 1);
1789 // Checks that two tabs with SSL timeouts in the same window work. Both
1790 // tabs only timeout after logging in.
1791 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, TwoBrokenTabs
) {
1792 SlowLoadBehindCaptivePortal(browser(), true);
1794 // Can't set the TabReloader HTTPS timeout on a new tab without doing some
1795 // acrobatics, so open a new tab at a normal page, and then navigate it to a
1797 MultiNavigationObserver navigation_observer
;
1798 CaptivePortalObserver
portal_observer(browser()->profile());
1799 ui_test_utils::NavigateToURLWithDisposition(
1801 URLRequestMockHTTPJob::GetMockUrl(
1802 base::FilePath(FILE_PATH_LITERAL("title2.html"))),
1804 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION
);
1806 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1807 ASSERT_EQ(3, tab_strip_model
->count());
1808 EXPECT_FALSE(CheckPending(browser()));
1809 EXPECT_EQ(0, portal_observer
.num_results_received());
1810 EXPECT_EQ(1, NumLoadingTabs());
1811 EXPECT_EQ(1, navigation_observer
.num_navigations());
1812 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1813 tab_strip_model
->GetWebContentsAt(2)));
1814 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1815 GetStateOfTabReloaderAt(browser(), 0));
1816 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1817 GetStateOfTabReloaderAt(browser(), 1));
1818 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
1819 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1820 GetStateOfTabReloaderAt(browser(), 2));
1821 ASSERT_EQ(2, tab_strip_model
->active_index());
1823 SlowLoadBehindCaptivePortal(browser(), false);
1825 tab_strip_model
->ActivateTabAt(1, true);
1826 Login(browser(), 2, 0);
1827 FailLoadsAfterLogin(browser(), 2);
1830 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, AbortLoad
) {
1831 SlowLoadBehindCaptivePortal(browser(), true);
1833 // Abandon the request.
1834 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1835 URLRequestTimeoutOnDemandJob::AbandonJobs(1);
1837 CaptivePortalObserver
portal_observer(browser()->profile());
1838 MultiNavigationObserver navigation_observer
;
1840 // Switch back to the hung tab from the login tab, and abort the navigation.
1841 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1842 tab_strip_model
->ActivateTabAt(0, true);
1843 chrome::Stop(browser());
1844 navigation_observer
.WaitForNavigations(1);
1846 EXPECT_EQ(0, NumBrokenTabs());
1847 EXPECT_EQ(0, portal_observer
.num_results_received());
1848 EXPECT_FALSE(CheckPending(browser()));
1849 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1850 GetStateOfTabReloaderAt(browser(), 0));
1852 tab_strip_model
->ActivateTabAt(1, true);
1853 Login(browser(), 0, 0);
1856 // Checks the case where the timed out tab is successfully navigated before
1858 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, NavigateBrokenTab
) {
1859 // Go to the error page.
1860 SlowLoadBehindCaptivePortal(browser(), true);
1861 FailLoadsWithoutLogin(browser(), 1);
1863 // Navigate the error tab to a non-error page.
1864 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1865 tab_strip_model
->ActivateTabAt(0, true);
1866 ui_test_utils::NavigateToURL(
1867 browser(), URLRequestMockHTTPJob::GetMockUrl(
1868 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
1869 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1870 GetStateOfTabReloaderAt(browser(), 0));
1872 // Simulate logging in.
1873 tab_strip_model
->ActivateTabAt(1, true);
1874 Login(browser(), 0, 0);
1877 // Checks that captive portal detection triggers correctly when a same-site
1878 // navigation is cancelled by a navigation to the same site.
1879 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
,
1880 NavigateLoadingTabToTimeoutSingleSite
) {
1881 RunNavigateLoadingTabToTimeoutTest(
1883 GURL(kMockHttpsUrl
),
1884 GURL(kMockHttpsUrl
),
1885 GURL(kMockHttpsUrl
));
1888 // Fails on Windows only, mostly on Win7. http://crbug.com/170033
1890 #define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
1891 DISABLED_NavigateLoadingTabToTimeoutTwoSites
1893 #define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
1894 NavigateLoadingTabToTimeoutTwoSites
1897 // Checks that captive portal detection triggers correctly when a same-site
1898 // navigation is cancelled by a navigation to another site.
1899 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
,
1900 MAYBE_NavigateLoadingTabToTimeoutTwoSites
) {
1901 RunNavigateLoadingTabToTimeoutTest(
1903 GURL(kMockHttpsUrl
),
1904 GURL(kMockHttpsUrl
),
1905 GURL(kMockHttpsUrl2
));
1908 // Checks that captive portal detection triggers correctly when a cross-site
1909 // navigation is cancelled by a navigation to yet another site.
1910 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
,
1911 NavigateLoadingTabToTimeoutThreeSites
) {
1912 RunNavigateLoadingTabToTimeoutTest(
1914 URLRequestMockHTTPJob::GetMockUrl(
1915 base::FilePath(FILE_PATH_LITERAL("title.html"))),
1916 GURL(kMockHttpsUrl
),
1917 GURL(kMockHttpsUrl2
));
1920 // Checks that navigating a timed out tab back clears its state.
1921 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, GoBack
) {
1922 // Navigate to a working page.
1923 ui_test_utils::NavigateToURL(
1925 URLRequestMockHTTPJob::GetMockUrl(
1926 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
1928 // Go to the error page.
1929 SlowLoadBehindCaptivePortal(browser(), true);
1930 FailLoadsWithoutLogin(browser(), 1);
1932 CaptivePortalObserver
portal_observer(browser()->profile());
1933 MultiNavigationObserver navigation_observer
;
1935 // Activate the error page tab again and go back.
1936 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1937 tab_strip_model
->ActivateTabAt(0, true);
1938 chrome::GoBack(browser(), CURRENT_TAB
);
1939 navigation_observer
.WaitForNavigations(1);
1941 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1942 tab_strip_model
->GetWebContentsAt(0)));
1943 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1944 GetStateOfTabReloaderAt(browser(), 0));
1945 EXPECT_EQ(0, portal_observer
.num_results_received());
1948 // Checks that navigating back to a timeout triggers captive portal detection.
1949 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, GoBackToTimeout
) {
1950 // Disable captive portal detection so the first navigation doesn't open a
1952 EnableCaptivePortalDetection(browser()->profile(), false);
1954 SlowLoadNoCaptivePortal(browser(), captive_portal::RESULT_INTERNET_CONNECTED
);
1956 // Navigate to a working page.
1957 ui_test_utils::NavigateToURL(
1958 browser(), URLRequestMockHTTPJob::GetMockUrl(
1959 base::FilePath(FILE_PATH_LITERAL("title2.html"))));
1960 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1961 GetStateOfTabReloaderAt(browser(), 0));
1963 EnableCaptivePortalDetection(browser()->profile(), true);
1965 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
1966 CaptivePortalTabReloader
* tab_reloader
=
1967 GetTabReloader(tab_strip_model
->GetActiveWebContents());
1968 ASSERT_TRUE(tab_reloader
);
1969 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
1971 // Go to the error page.
1972 MultiNavigationObserver navigation_observer
;
1973 CaptivePortalObserver
portal_observer(browser()->profile());
1974 chrome::GoBack(browser(), CURRENT_TAB
);
1976 // Wait for the check triggered by the broken tab and for the login tab to
1978 portal_observer
.WaitForResults(1);
1979 navigation_observer
.WaitForNavigations(1);
1980 // Make sure the request has been issued.
1981 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
1983 EXPECT_EQ(1, portal_observer
.num_results_received());
1984 ASSERT_FALSE(CheckPending(browser()));
1985 ASSERT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
1986 portal_observer
.captive_portal_result());
1988 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
1989 GetStateOfTabReloaderAt(browser(), 0));
1990 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
1991 GetStateOfTabReloaderAt(browser(), 1));
1992 ASSERT_TRUE(IsLoginTab(browser()->tab_strip_model()->GetWebContentsAt(1)));
1994 ASSERT_EQ(2, tab_strip_model
->count());
1995 EXPECT_EQ(1, tab_strip_model
->active_index());
1996 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
1997 tab_strip_model
->GetWebContentsAt(1)));
1998 EXPECT_EQ(1, NumLoadingTabs());
2000 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
2001 Login(browser(), 1, 0);
2002 FailLoadsAfterLogin(browser(), 1);
2005 // Checks that reloading a timeout triggers captive portal detection.
2006 // Much like the last test, though the captive portal is disabled before
2007 // the inital navigation, rather than captive portal detection.
2008 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, ReloadTimeout
) {
2009 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
2011 // Do the first navigation while not behind a captive portal.
2012 TabStripModel
* tab_strip_model
= browser()->tab_strip_model();
2013 CaptivePortalObserver
portal_observer(browser()->profile());
2014 ui_test_utils::NavigateToURL(browser(), GURL(kMockHttpsUrl
));
2015 ASSERT_EQ(0, portal_observer
.num_results_received());
2016 ASSERT_EQ(1, tab_strip_model
->count());
2018 // A captive portal spontaneously appears.
2019 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
2021 CaptivePortalTabReloader
* tab_reloader
=
2022 GetTabReloader(tab_strip_model
->GetActiveWebContents());
2023 ASSERT_TRUE(tab_reloader
);
2024 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta());
2026 MultiNavigationObserver navigation_observer
;
2027 tab_strip_model
->GetActiveWebContents()->GetController().Reload(true);
2029 // Wait for the check triggered by the broken tab and for the login tab to
2031 portal_observer
.WaitForResults(1);
2032 navigation_observer
.WaitForNavigations(1);
2033 // Make sure the request has been issued.
2034 URLRequestTimeoutOnDemandJob::WaitForJobs(1);
2036 ASSERT_EQ(1, portal_observer
.num_results_received());
2037 ASSERT_FALSE(CheckPending(browser()));
2038 ASSERT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
2039 portal_observer
.captive_portal_result());
2041 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
2042 GetStateOfTabReloaderAt(browser(), 0));
2043 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2044 GetStateOfTabReloaderAt(browser(), 1));
2045 ASSERT_TRUE(IsLoginTab(tab_strip_model
->GetWebContentsAt(1)));
2047 ASSERT_EQ(2, tab_strip_model
->count());
2048 EXPECT_EQ(1, tab_strip_model
->active_index());
2049 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
2050 tab_strip_model
->GetWebContentsAt(1)));
2051 EXPECT_EQ(1, NumLoadingTabs());
2053 SetSlowSSLLoadTime(tab_reloader
, base::TimeDelta::FromDays(1));
2054 Login(browser(), 1, 0);
2055 FailLoadsAfterLogin(browser(), 1);
2058 // Checks the case where there are two windows, and there's an SSL timeout in
2059 // the background one.
2060 // Disabled: http://crbug.com/134357
2061 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, DISABLED_TwoWindows
) {
2063 new Browser(Browser::CreateParams(browser()->profile(),
2064 browser()->host_desktop_type()));
2065 // Navigate the new browser window so it'll be shown and we can pick the
2067 ui_test_utils::NavigateToURL(browser2
, GURL(content::kAboutBlankURL
));
2069 // Generally, |browser2| will be the active window. However, if the
2070 // original browser window lost focus before creating the new one, such as
2071 // when running multiple tests at once, the original browser window may
2072 // remain the profile's active window.
2073 Browser
* active_browser
=
2074 chrome::FindTabbedBrowser(browser()->profile(), true,
2075 browser()->host_desktop_type());
2076 Browser
* inactive_browser
;
2077 if (active_browser
== browser2
) {
2078 // When only one test is running at a time, the new browser will probably be
2079 // on top, but when multiple tests are running at once, this is not
2081 inactive_browser
= browser();
2083 ASSERT_EQ(active_browser
, browser());
2084 inactive_browser
= browser2
;
2087 CaptivePortalObserver
portal_observer(browser()->profile());
2088 MultiNavigationObserver navigation_observer
;
2090 // Navigate the tab in the inactive browser to an SSL timeout. Have to use
2091 // chrome::NavigateParams and NEW_BACKGROUND_TAB to avoid activating the
2093 chrome::NavigateParams
params(inactive_browser
,
2094 GURL(kMockHttpsQuickTimeoutUrl
),
2095 content::PAGE_TRANSITION_TYPED
);
2096 params
.disposition
= NEW_BACKGROUND_TAB
;
2097 params
.window_action
= chrome::NavigateParams::NO_ACTION
;
2098 ui_test_utils::NavigateToURL(¶ms
);
2099 navigation_observer
.WaitForNavigations(2);
2101 // Make sure the active window hasn't changed, and its new tab is
2103 ASSERT_EQ(active_browser
,
2104 chrome::FindTabbedBrowser(browser()->profile(), true,
2105 browser()->host_desktop_type()));
2106 ASSERT_EQ(1, active_browser
->tab_strip_model()->active_index());
2108 // Check that the only two navigated tabs were the new error tab in the
2109 // backround windows, and the login tab in the active window.
2110 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
2111 inactive_browser
->tab_strip_model()->GetWebContentsAt(1)));
2112 EXPECT_EQ(1, navigation_observer
.NumNavigationsForTab(
2113 active_browser
->tab_strip_model()->GetWebContentsAt(1)));
2114 EXPECT_EQ(0, NumLoadingTabs());
2116 // Check captive portal test results.
2117 portal_observer
.WaitForResults(1);
2118 ASSERT_EQ(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
2119 portal_observer
.captive_portal_result());
2120 EXPECT_EQ(1, portal_observer
.num_results_received());
2122 // Check the inactive browser.
2123 EXPECT_EQ(2, inactive_browser
->tab_strip_model()->count());
2124 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2125 GetStateOfTabReloaderAt(inactive_browser
, 0));
2126 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL
,
2127 GetStateOfTabReloaderAt(inactive_browser
, 1));
2129 // Check the active browser.
2130 ASSERT_EQ(2, active_browser
->tab_strip_model()->count());
2131 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2132 GetStateOfTabReloaderAt(active_browser
, 0));
2133 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE
,
2134 GetStateOfTabReloaderAt(active_browser
, 1));
2136 IsLoginTab(active_browser
->tab_strip_model()->GetWebContentsAt(1)));
2138 // Simulate logging in.
2139 Login(active_browser
, 0, 1);
2142 // An HTTP page redirects to an HTTPS page loads slowly before timing out. A
2143 // captive portal is found, and then the user logs in before the original page
2145 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpToHttpsRedirectLogin
) {
2146 ASSERT_TRUE(test_server()->Start());
2147 SlowLoadBehindCaptivePortal(
2150 test_server()->GetURL(CreateServerRedirect(kMockHttpsUrl
)),
2153 Login(browser(), 1, 0);
2154 FailLoadsAfterLogin(browser(), 1);
2157 // An HTTPS page redirects to an HTTP page.
2158 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HttpsToHttpRedirect
) {
2159 // Use an HTTPS server for the top level page.
2160 net::SpawnedTestServer
https_server(
2161 net::SpawnedTestServer::TYPE_HTTPS
, net::SpawnedTestServer::kLocalhost
,
2162 base::FilePath(FILE_PATH_LITERAL("chrome/test/data")));
2163 ASSERT_TRUE(https_server
.Start());
2165 GURL http_timeout_url
=
2166 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT
);
2168 // 2 navigations due to the Link Doctor.
2169 NavigateToPageExpectNoTest(
2171 https_server
.GetURL(CreateServerRedirect(http_timeout_url
.spec())),
2175 // Tests the 511 response code, along with an HTML redirect to a login page.
2176 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, Status511
) {
2177 SetUpCaptivePortalService(browser()->profile(),
2178 GURL(kMockCaptivePortal511Url
));
2179 SlowLoadBehindCaptivePortal(browser(), true, GURL(kMockHttpsUrl
), 2, 2);
2180 Login(browser(), 1, 0);
2181 FailLoadsAfterLogin(browser(), 1);
2184 // HSTS redirects an HTTP request to HTTPS, and the request then times out.
2185 // A captive portal is then detected, and a login tab opened, before logging
2187 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest
, HstsLogin
) {
2188 GURL::Replacements replacements
;
2189 std::string scheme
= "http";
2190 replacements
.SetSchemeStr(scheme
);
2191 GURL http_timeout_url
= GURL(kMockHttpsUrl
).ReplaceComponents(replacements
);
2193 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT
);
2194 content::BrowserThread::PostTask(
2195 content::BrowserThread::IO
, FROM_HERE
,
2196 base::Bind(&AddHstsHost
,
2197 make_scoped_refptr(browser()->profile()->GetRequestContext()),
2198 http_timeout_url
.host()));
2200 SlowLoadBehindCaptivePortal(browser(), true, http_timeout_url
, 1, 1);
2201 Login(browser(), 1, 0);
2202 FailLoadsAfterLogin(browser(), 1);