Fix build break
[chromium-blink-merge.git] / chrome / browser / captive_portal / captive_portal_browsertest.cc
blob90ac2b984ff303d5dffb6c0af9e35773f7752513
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.
5 #include <map>
6 #include <set>
8 #include "base/basictypes.h"
9 #include "base/bind.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 {
63 namespace {
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
69 // TestServer.
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
88 // response.
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
101 // navigations.
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
110 // captive portal.
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 {
118 public:
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);
137 private:
138 friend class URLRequestMockCaptivePortalJobFactory;
140 // Operation to perform on jobs when removing them from |job_list_|.
141 enum EndJobOperation {
142 FAIL_JOBS,
143 ABANDON_JOBS,
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
151 // from the list.
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
168 // waiting for jobs.
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
178 // on regressions.
179 static int num_jobs_started_;
181 // Head of linked list of jobs that have been started and are now waiting to
182 // be timed out.
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_;
201 job_list_ = this;
202 ++num_jobs_started_;
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();
211 // static
212 void URLRequestTimeoutOnDemandJob::WaitForJobs(int num_jobs) {
213 content::BrowserThread::PostTask(
214 content::BrowserThread::IO, FROM_HERE,
215 base::Bind(&URLRequestTimeoutOnDemandJob::WaitForJobsOnIOThread,
216 num_jobs));
217 content::RunMessageLoop();
220 // static
221 void URLRequestTimeoutOnDemandJob::FailJobs(int expected_num_jobs) {
222 content::BrowserThread::PostTask(
223 content::BrowserThread::IO, FROM_HERE,
224 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
225 expected_num_jobs,
226 FAIL_JOBS));
229 // static
230 void URLRequestTimeoutOnDemandJob::AbandonJobs(int expected_num_jobs) {
231 content::BrowserThread::PostTask(
232 content::BrowserThread::IO, FROM_HERE,
233 base::Bind(&URLRequestTimeoutOnDemandJob::FailOrAbandonJobsOnIOThread,
234 expected_num_jobs,
235 ABANDON_JOBS));
238 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
239 net::URLRequest* request, net::NetworkDelegate* network_delegate)
240 : net::URLRequestJob(request, network_delegate),
241 next_job_(NULL) {
244 URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() {
245 // All hanging jobs should have failed or been abandoned before being
246 // destroyed.
247 EXPECT_FALSE(RemoveFromList());
250 bool URLRequestTimeoutOnDemandJob::RemoveFromList() {
251 URLRequestTimeoutOnDemandJob** job = &job_list_;
252 while (*job) {
253 if (*job == this) {
254 *job = next_job_;
255 next_job_ = NULL;
256 return true;
258 job = &next_job_;
261 // If the job wasn't in this list, |next_job_| should be NULL.
262 EXPECT_FALSE(next_job_);
263 return false;
266 // static
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();
278 // static
279 void URLRequestTimeoutOnDemandJob::MaybeStopWaitingForJobsOnIOThread() {
280 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
281 if (num_jobs_to_wait_for_ == 0)
282 return;
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());
297 // static
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;
306 int num_jobs = 0;
307 while (job_list_) {
308 ++num_jobs;
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 {
334 public:
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
338 // once.
339 static void AddUrlHandlers();
341 // Sets whether or not there is a captive portal. Outstanding requests are
342 // not affected.
343 static void SetBehindCaptivePortal(bool behind_captive_portal);
345 private:
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
354 // actual behavior.
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;
366 // static
367 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() {
368 content::BrowserThread::PostTask(
369 content::BrowserThread::IO, FROM_HERE,
370 base::Bind(
371 &URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread));
374 // static
375 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(
376 bool behind_captive_portal) {
377 content::BrowserThread::PostTask(
378 content::BrowserThread::IO, FROM_HERE,
379 base::Bind(
380 &URLRequestMockCaptivePortalJobFactory::
381 SetBehindCaptivePortalOnIOThread,
382 behind_captive_portal));
385 // static
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);
404 // static
405 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread(
406 bool behind_captive_portal) {
407 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
408 behind_captive_portal_ = behind_captive_portal;
411 // static
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(
429 request,
430 network_delegate,
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(
439 request,
440 network_delegate,
441 root_http.Append(FILE_PATH_LITERAL("title2.html")));
442 } else {
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(
452 request,
453 network_delegate,
454 root_http.Append(FILE_PATH_LITERAL("captive_portal/page511.html")));
456 return new URLRequestMockHTTPJob(
457 request,
458 network_delegate,
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(
464 request,
465 network_delegate,
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
477 // Profiles.
478 int NumLoadingTabs() {
479 int num_loading_tabs = 0;
480 for (TabContentsIterator it; !it.done(); it.Next()) {
481 if (it->IsLoading())
482 ++num_loading_tabs;
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 {
495 public:
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_; }
511 private:
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())
566 return 0;
567 return tab_navigations->second;
570 void MultiNavigationObserver::Observe(
571 int type,
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();
577 ++num_navigations_;
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 {
595 public:
596 FailLoadsAfterLoginObserver();
597 virtual ~FailLoadsAfterLoginObserver();
599 void WaitForNavigations();
601 private:
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()) {
630 if (it->IsLoading())
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(
652 int type,
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))
664 return;
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 {
678 public:
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_;
692 private:
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_;
707 Profile* profile_;
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),
723 profile_(profile),
724 captive_portal_service_(
725 CaptivePortalServiceFactory::GetForProfile(profile)),
726 captive_portal_result_(
727 captive_portal_service_->last_detection_result()) {
728 registrar_.Add(this,
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(
746 int type,
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(),
757 results->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) {
777 FAIL();
778 return;
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);
786 } // namespace
788 class CaptivePortalBrowserTest : public InProcessBrowserTest {
789 public:
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
805 // check.
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,
814 int index) const;
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,
831 const GURL& url,
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
920 // tab.
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
924 // logging in.
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;
941 private:
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
956 // browser tests.
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,
1009 int index) const {
1010 return GetStateOfTabReloader(
1011 browser->tab_strip_model()->GetWebContentsAt(index));
1014 int CaptivePortalBrowserTest::NumTabsWithState(
1015 CaptivePortalTabReloader::State state) const {
1016 int num_tabs = 0;
1017 for (TabContentsIterator it; !it.done(); it.Next()) {
1018 if (GetStateOfTabReloader(*it) == state)
1019 ++num_tabs;
1021 return num_tabs;
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(
1033 Browser* browser,
1034 const GURL& url,
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),
1064 CURRENT_TAB,
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(
1111 browser,
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
1127 // navigations.
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(
1142 Browser* browser,
1143 bool expect_open_login_tab) {
1144 SlowLoadBehindCaptivePortal(browser,
1145 expect_open_login_tab,
1146 GURL(kMockHttpsUrl),
1151 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
1152 Browser* browser,
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
1170 // have completed.
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,
1183 hanging_url,
1184 CURRENT_TAB,
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)));
1202 } else {
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(
1228 Browser* browser,
1229 bool expect_open_login_tab) {
1230 FastErrorBehindCaptivePortal(browser,
1231 expect_open_login_tab,
1232 GURL(kMockHttpsQuickTimeoutUrl));
1235 void CaptivePortalBrowserTest::FastErrorBehindCaptivePortal(
1236 Browser* browser,
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
1252 // have completed.
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,
1265 error_url,
1266 CURRENT_TAB,
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)));
1283 } else {
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(
1468 Browser* browser,
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(),
1506 CURRENT_TAB,
1507 content::PAGE_TRANSITION_TYPED,
1508 false));
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
1544 // error page.
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
1599 // be a timeout.
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
1648 // window.
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(
1725 string16(),
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);
1781 // Close login tab.
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
1797 // timeout.
1798 MultiNavigationObserver navigation_observer;
1799 CaptivePortalObserver portal_observer(browser()->profile());
1800 ui_test_utils::NavigateToURLWithDisposition(
1801 browser(),
1802 URLRequestMockHTTPJob::GetMockUrl(
1803 base::FilePath(FILE_PATH_LITERAL("title2.html"))),
1804 NEW_FOREGROUND_TAB,
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
1858 // logging in.
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(
1883 browser(),
1884 GURL(kMockHttpsUrl),
1885 GURL(kMockHttpsUrl),
1886 GURL(kMockHttpsUrl));
1889 // Fails on Windows only, mostly on Win7. http://crbug.com/170033
1890 #if defined(OS_WIN)
1891 #define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
1892 DISABLED_NavigateLoadingTabToTimeoutTwoSites
1893 #else
1894 #define MAYBE_NavigateLoadingTabToTimeoutTwoSites \
1895 NavigateLoadingTabToTimeoutTwoSites
1896 #endif
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(
1903 browser(),
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(
1914 browser(),
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(
1925 browser(),
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
1952 // login tab.
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
1978 // stop loading.
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
2031 // stop loading.
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) {
2063 Browser* browser2 =
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
2067 // active window.
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
2081 // guaranteed.
2082 inactive_browser = browser();
2083 } else {
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
2093 // window.
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(&params);
2100 navigation_observer.WaitForNavigations(2);
2102 // Make sure the active window hasn't changed, and its new tab is
2103 // active.
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));
2136 EXPECT_TRUE(
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
2145 // times out.
2146 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpToHttpsRedirectLogin) {
2147 ASSERT_TRUE(test_server()->Start());
2148 SlowLoadBehindCaptivePortal(
2149 browser(),
2150 true,
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(
2171 browser(),
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
2187 // in.
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