Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(107)

Side by Side Diff: chrome/browser/captive_portal/captive_portal_browsertest.cc

Issue 10020051: Open a login tab on captive portal detection on SSL loads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Response to comments Created 8 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « build/common.gypi ('k') | chrome/browser/captive_portal/captive_portal_login_detector.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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.
4
5 #include <map>
6 #include <set>
7
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/file_path.h"
13 #include "base/message_loop.h"
14 #include "base/path_service.h"
15 #include "base/utf_string_conversions.h"
16 #include "chrome/browser/captive_portal/captive_portal_service.h"
17 #include "chrome/browser/captive_portal/captive_portal_service_factory.h"
18 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
19 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
20 #include "chrome/browser/net/url_request_mock_util.h"
21 #include "chrome/browser/prefs/pref_service.h"
22 #include "chrome/browser/profiles/profile.h"
23 #include "chrome/browser/ui/browser.h"
24 #include "chrome/browser/ui/browser_finder.h"
25 #include "chrome/browser/ui/browser_navigator.h"
26 #include "chrome/browser/ui/tab_contents/tab_contents_iterator.h"
27 #include "chrome/browser/ui/tab_contents/tab_contents_wrapper.h"
28 #include "chrome/common/chrome_notification_types.h"
29 #include "chrome/common/chrome_paths.h"
30 #include "chrome/common/chrome_switches.h"
31 #include "chrome/common/pref_names.h"
32 #include "chrome/test/base/in_process_browser_test.h"
33 #include "chrome/test/base/ui_test_utils.h"
34 #include "content/public/browser/browser_thread.h"
35 #include "content/public/browser/navigation_controller.h"
36 #include "content/public/browser/notification_observer.h"
37 #include "content/public/browser/notification_registrar.h"
38 #include "content/public/browser/notification_service.h"
39 #include "content/public/browser/notification_types.h"
40 #include "content/public/browser/render_view_host.h"
41 #include "content/public/browser/web_contents.h"
42 #include "content/public/common/url_constants.h"
43 #include "content/test/net/url_request_failed_job.h"
44 #include "content/test/net/url_request_mock_http_job.h"
45 #include "net/base/net_errors.h"
46 #include "net/url_request/url_request_filter.h"
47 #include "net/url_request/url_request_job.h"
48 #include "net/url_request/url_request_status.h"
49 #include "testing/gtest/include/gtest/gtest.h"
50
51 using content::BrowserThread;
52
53 namespace captive_portal {
54
55 namespace {
56
57 // Path of the fake login page, when using the TestServer.
58 const char* const kTestServerLoginPath = "files/captive_portal/login.html";
59
60 // Path of a page with an iframe that has a mock SSL timeout, when using the
61 // TestServer.
62 const char* const kTestServerIframeTimeoutPath =
63 "files/captive_portal/iframe_timeout.html";
64
65 // The following URLs each have two different behaviors, depending on whether
66 // URLRequestMockCaptivePortalJobFactory is currently simulating the presence
67 // of a captive portal or not.
68
69 // A mock URL for the CaptivePortalService's |test_url|. When behind a captive
70 // portal, this URL return a mock login page. When connected to the Internet,
71 // it returns a 204 response.
72 const char* const kMockCaptivePortalTestUrl =
73 "http://mock.captive.portal/captive_portal_test/";
74
75 // When behind a captive portal, this URL hangs without committing until a call
76 // to URLRequestTimeoutOnDemandJob::FailRequests. When that function is called,
77 // the request will time out.
78 //
79 // When connected to the Internet, this URL returns a non-error page.
80 const char* const kMockHttpsUrl = "https://mock.captive.portal/long_timeout/";
81
82 // Same as kMockHttpsUrl, except the timeout happens instantly.
83 const char* const kMockHttpsQuickTimeoutUrl =
84 "https://mock.captive.portal/quick_timeout/";
85
86 // Expected title of a tab once an HTTPS load completes, when not behind a
87 // captive portal.
88 const char* const kInternetConnectedTitle = "Title Of Awesomeness";
89
90 // A URL request job that hangs until FailRequests() is called. Started jobs
91 // are stored in a static class variable containing a linked list so that
92 // FailRequests() can locate them.
93 class URLRequestTimeoutOnDemandJob : public net::URLRequestJob,
94 public base::NonThreadSafe {
95 public:
96 // net::URLRequestJob:
97 virtual void Start() OVERRIDE;
98
99 // All the public static methods below can be called on any thread.
100
101 // Fails all active URLRequestFailOnDemandJobs with connection timeouts.
102 // Must only be called when there are requests that have been started but not
103 // yet timed out.
104 static void FailRequests();
105
106 // Clears the |waiting_jobs_list_| without having the jobs return anything.
107 // Used to allow an assertion that jobs are not in the |waiting_jobs_list_|
108 // when destroyed. Must only be called when there are requests that have
109 // been started but not yet timed out.
110 static void AbandonRequests();
111
112 private:
113 friend class URLRequestMockCaptivePortalJobFactory;
114
115 explicit URLRequestTimeoutOnDemandJob(net::URLRequest* request);
116 virtual ~URLRequestTimeoutOnDemandJob();
117
118 // Attempts to removes |this| from |jobs_|. Returns true if it was removed
119 // from the list.
120 bool RemoveFromList();
121
122 // These do all the work of the corresponding public functions, with the only
123 // difference being that they must be called on the IO thread.
124 static void FailRequestsOnIOThread();
125 static void AbandonRequestsOnIOThread();
126
127 // Head of linked list of jobs that have been started and are now waiting to
128 // be timed out.
129 static URLRequestTimeoutOnDemandJob* job_list_;
130
131 // The next job that had been started but not yet timed out.
132 URLRequestTimeoutOnDemandJob* next_job_;
133
134 DISALLOW_COPY_AND_ASSIGN(URLRequestTimeoutOnDemandJob);
135 };
136
137 URLRequestTimeoutOnDemandJob* URLRequestTimeoutOnDemandJob::job_list_ = NULL;
138
139 void URLRequestTimeoutOnDemandJob::Start() {
140 EXPECT_TRUE(CalledOnValidThread());
141
142 // Insert at start of the list.
143 next_job_ = job_list_;
144 job_list_ = this;
145 }
146
147 // static
148 void URLRequestTimeoutOnDemandJob::FailRequests() {
149 content::BrowserThread::PostTask(
150 content::BrowserThread::IO, FROM_HERE,
151 base::Bind(&URLRequestTimeoutOnDemandJob::FailRequestsOnIOThread));
152 }
153
154 // static
155 void URLRequestTimeoutOnDemandJob::AbandonRequests() {
156 content::BrowserThread::PostTask(
157 content::BrowserThread::IO, FROM_HERE,
158 base::Bind(&URLRequestTimeoutOnDemandJob::AbandonRequestsOnIOThread));
159 }
160
161 URLRequestTimeoutOnDemandJob::URLRequestTimeoutOnDemandJob(
162 net::URLRequest* request)
163 : net::URLRequestJob(request),
164 next_job_(NULL) {
165 }
166
167 URLRequestTimeoutOnDemandJob::~URLRequestTimeoutOnDemandJob() {
168 // |this| shouldn't be in the list.
169 EXPECT_FALSE(RemoveFromList());
170 }
171
172 bool URLRequestTimeoutOnDemandJob::RemoveFromList() {
173 URLRequestTimeoutOnDemandJob** job = &job_list_;
cbentzel 2012/05/31 20:50:43 Ah, you know the ** trick for iterating and removi
mmenke 2012/05/31 21:12:58 Does that put me among some sort of elite hacker c
174 while (*job) {
175 if (*job == this) {
176 *job = next_job_;
177 next_job_ = NULL;
178 return true;
179 }
180 job = &next_job_;
181 }
182
183 // If the job wasn't in this list, |next_job_| should be NULL.
184 EXPECT_FALSE(next_job_);
185 return false;
186 }
187
188 // static
189 void URLRequestTimeoutOnDemandJob::FailRequestsOnIOThread() {
190 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
191 EXPECT_TRUE(job_list_);
192 while (job_list_) {
193 URLRequestTimeoutOnDemandJob* job = job_list_;
194 // Since the error notification may result in the job's destruction, remove
195 // it from the job list before the error.
196 EXPECT_TRUE(job->RemoveFromList());
197 job->NotifyStartError(net::URLRequestStatus(
198 net::URLRequestStatus::FAILED,
199 net::ERR_CONNECTION_TIMED_OUT));
200 }
201 }
202
203 // static
204 void URLRequestTimeoutOnDemandJob::AbandonRequestsOnIOThread() {
205 ASSERT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
206 EXPECT_TRUE(job_list_);
207 while (job_list_)
208 EXPECT_TRUE(job_list_->RemoveFromList());
209 }
210
211 // URLRequestCaptivePortalJobFactory emulates captive portal behavior.
212 // Initially, it emulates being behind a captive portal. When
213 // SetBehindCaptivePortal(false) is called, it emulates behavior when not behind
214 // a captive portal. The class itself is never instantiated.
215 //
216 // It handles requests for kMockCaptivePortalTestUrl, kMockHttpsUrl, and
217 // kMockHttpsQuickTimeoutUrl.
218 class URLRequestMockCaptivePortalJobFactory {
219 public:
220 // The public static methods below can be called on any thread.
221
222 // Adds the testing URLs to the net::URLRequestFilter. Should only be called
223 // once.
224 static void AddUrlHandlers();
225
226 // Sets whether or not there is a captive portal. Outstanding requests are
227 // not affected.
228 static void SetBehindCaptivePortal(bool behind_captive_portal);
229
230 private:
231 // These do all the work of the corresponding public functions, with the only
232 // difference being that they must be called on the IO thread.
233 static void AddUrlHandlersOnIOThread();
234 static void SetBehindCaptivePortalOnIOThread(bool behind_captive_portal);
235
236 // Returns a URLRequestJob that reflects the current captive portal state
237 // for the URLs: kMockCaptivePortalTestUrl, kMockHttpsUrl, and
238 // kMockHttpsQuickTimeoutUrl. See documentation of individual URLs for
239 // actual behavior.
240 static net::URLRequestJob* Factory(net::URLRequest* request,
241 const std::string& scheme);
242
243 static bool behind_captive_portal_;
244
245 DISALLOW_IMPLICIT_CONSTRUCTORS(URLRequestMockCaptivePortalJobFactory);
246 };
247
248 bool URLRequestMockCaptivePortalJobFactory::behind_captive_portal_ = true;
249
250 // static
251 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlers() {
252 content::BrowserThread::PostTask(
253 content::BrowserThread::IO, FROM_HERE,
254 base::Bind(
255 &URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread));
256 }
257
258 // static
259 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(
260 bool behind_captive_portal) {
261 content::BrowserThread::PostTask(
262 content::BrowserThread::IO, FROM_HERE,
263 base::Bind(
264 &URLRequestMockCaptivePortalJobFactory::
265 SetBehindCaptivePortalOnIOThread,
266 behind_captive_portal));
267 }
268
269 // static
270 void URLRequestMockCaptivePortalJobFactory::AddUrlHandlersOnIOThread() {
271 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
272 net::URLRequestFilter* filter = net::URLRequestFilter::GetInstance();
273 filter->AddHostnameHandler("http", "mock.captive.portal",
274 URLRequestMockCaptivePortalJobFactory::Factory);
275 filter->AddHostnameHandler("https", "mock.captive.portal",
276 URLRequestMockCaptivePortalJobFactory::Factory);
277 }
278
279 // static
280 void URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortalOnIOThread(
281 bool behind_captive_portal) {
282 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
283 behind_captive_portal_ = behind_captive_portal;
284 }
285
286 // static
287 net::URLRequestJob* URLRequestMockCaptivePortalJobFactory::Factory(
288 net::URLRequest* request,
289 const std::string& scheme) {
290 EXPECT_TRUE(BrowserThread::CurrentlyOn(BrowserThread::IO));
291
292 // The PathService is threadsafe.
293 FilePath root_http;
294 PathService::Get(chrome::DIR_TEST_DATA, &root_http);
295
296 if (scheme == "https") {
297 if (behind_captive_portal_) {
298 // If not logged in to the captive portal, HTTPS requests will time out,
299 // either immediately on on demand.
300 if (request->url() == GURL(kMockHttpsQuickTimeoutUrl))
301 return new URLRequestFailedJob(request, net::ERR_CONNECTION_TIMED_OUT);
302 return new URLRequestTimeoutOnDemandJob(request);
303 }
304 // Once logged in to the portal, HTTPS requests return the page that was
305 // actually requested.
306 return new URLRequestMockHTTPJob(
307 request,
308 root_http.Append(FILE_PATH_LITERAL("title2.html")));
309 }
310
311 // The URL is the captive portal test URL.
312
313 if (behind_captive_portal_) {
314 // Prior to logging in to the portal, HTTP requests go to the login page.
315 return new URLRequestMockHTTPJob(
316 request,
317 root_http.Append(
318 FILE_PATH_LITERAL("captive_portal/login.html")));
319 }
320 // After logging in to the portal, the test URL returns a 204 response.
321 return new URLRequestMockHTTPJob(
322 request,
323 root_http.Append(
324 FILE_PATH_LITERAL("captive_portal/page204.html")));
325 }
326
327 // Creates a server-side redirect for use with the TestServer.
328 std::string CreateServerRedirect(const std::string& dest_url) {
329 const char* const kServerRedirectBase = "server-redirect?";
330 return kServerRedirectBase + dest_url;
331 }
332
333 // Returns the total number of loading tabs across all Browsers, for all
334 // Profiles.
335 int NumLoadingTabs() {
336 int num_loading_tabs = 0;
337 for (TabContentsIterator tab_contents_it;
338 !tab_contents_it.done();
339 ++tab_contents_it) {
340 if (tab_contents_it->web_contents()->IsLoading())
341 ++num_loading_tabs;
342 }
343 return num_loading_tabs;
344 }
345
346 bool IsLoginTab(TabContentsWrapper* tab_contents) {
347 return tab_contents->captive_portal_tab_helper()->IsLoginTab();
348 }
349
350 // Tracks how many times each tab has been navigated since the Observer was
351 // created. The standard TestNavigationObserver can only watch specific
352 // pre-existing tabs or loads in serial for all tabs.
353 class MultiNavigationObserver : public content::NotificationObserver {
354 public:
355 MultiNavigationObserver();
356 virtual ~MultiNavigationObserver();
357
358 // Waits for exactly |num_navigations_to_wait_for| LOAD_STOP
359 // notifications to have occurred since the construction of |this|. More
360 // navigations than expected occuring will trigger a expect failure.
361 void WaitForNavigations(int num_navigations_to_wait_for);
362
363 // Returns the number of LOAD_STOP events that have occurred for
364 // |web_contents| since this was constructed.
365 int NumNavigationsForTab(content::WebContents* web_contents) const;
366
367 // The number of LOAD_STOP events since |this| was created.
368 int num_navigations() const { return num_navigations_; }
369
370 private:
371 typedef std::map<content::WebContents*, int> TabNavigationMap;
372
373 // content::NotificationObserver:
374 virtual void Observe(int type, const content::NotificationSource& source,
375 const content::NotificationDetails& details) OVERRIDE;
376
377 int num_navigations_;
378
379 // Map of how many times each tab has navigated since |this| was created.
380 TabNavigationMap tab_navigation_map_;
381
382 // Total number of navigations to wait for. Value only matters when
383 // |waiting_for_navigation_| is true.
384 int num_navigations_to_wait_for_;
385
386 // True if WaitForNavigations has been called, until
387 // |num_navigations_to_wait_for_| have been observed.
388 bool waiting_for_navigation_;
389
390 content::NotificationRegistrar registrar_;
391
392 DISALLOW_COPY_AND_ASSIGN(MultiNavigationObserver);
393 };
394
395 MultiNavigationObserver::MultiNavigationObserver()
396 : num_navigations_(0),
397 num_navigations_to_wait_for_(0),
398 waiting_for_navigation_(false) {
399 registrar_.Add(this, content::NOTIFICATION_LOAD_STOP,
400 content::NotificationService::AllSources());
401 }
402
403 MultiNavigationObserver::~MultiNavigationObserver() {
404 }
405
406 void MultiNavigationObserver::WaitForNavigations(
407 int num_navigations_to_wait_for) {
408 // Shouldn't already be waiting for navigations.
409 EXPECT_FALSE(waiting_for_navigation_);
410 EXPECT_LT(0, num_navigations_to_wait_for);
411 if (num_navigations_ < num_navigations_to_wait_for) {
412 num_navigations_to_wait_for_ = num_navigations_to_wait_for;
413 waiting_for_navigation_ = true;
414 ui_test_utils::RunMessageLoop();
415 EXPECT_FALSE(waiting_for_navigation_);
416 }
417 EXPECT_EQ(num_navigations_, num_navigations_to_wait_for);
418 }
419
420 int MultiNavigationObserver::NumNavigationsForTab(
421 content::WebContents* web_contents) const {
422 TabNavigationMap::const_iterator tab_navigations =
423 tab_navigation_map_.find(web_contents);
424 if (tab_navigations == tab_navigation_map_.end())
425 return 0;
426 return tab_navigations->second;
427 }
428
429 void MultiNavigationObserver::Observe(
430 int type,
431 const content::NotificationSource& source,
432 const content::NotificationDetails& details) {
433 ASSERT_EQ(type, content::NOTIFICATION_LOAD_STOP);
434 content::NavigationController* controller =
435 content::Source<content::NavigationController>(source).ptr();
436 ++num_navigations_;
437 ++tab_navigation_map_[controller->GetWebContents()];
438 if (waiting_for_navigation_ &&
439 num_navigations_to_wait_for_ == num_navigations_) {
440 waiting_for_navigation_ = false;
441 MessageLoopForUI::current()->Quit();
442 }
443 }
444
445 // An observer for watching the CaptivePortalService. It tracks the last
446 // received result and the total number of received results.
447 class CaptivePortalObserver : public content::NotificationObserver {
448 public:
449 explicit CaptivePortalObserver(Profile* profile);
450
451 // Runs the message loop until until at exactly |update_count| capitive portal
452 // results have been received, since this creation of |this|. Expects no
453 // additional captive portal results.
454 void WaitForResults(int num_results_to_wait_for);
455
456 int num_results_received() const { return num_results_received_; }
457
458 Result captive_portal_result() const {
459 return captive_portal_result_;
460 }
461
462 private:
463 // Records results and exits the message loop, if needed.
464 void Observe(int type,
465 const content::NotificationSource& source,
466 const content::NotificationDetails& details);
467
468 // Number of times OnPortalResult has been called since construction.
469 int num_results_received_;
470
471 // If WaitForResults was called, the total number of updates for which to
472 // wait. Value doesn't matter when |waiting_for_result_| is false.
473 int num_results_to_wait_for_;
474
475 bool waiting_for_result_;
476
477 Profile* profile_;
478
479 CaptivePortalService* captive_portal_service_;
480
481 // Last result received.
482 Result captive_portal_result_;
483
484 content::NotificationRegistrar registrar_;
485
486 DISALLOW_COPY_AND_ASSIGN(CaptivePortalObserver);
487 };
488
489 CaptivePortalObserver::CaptivePortalObserver(Profile* profile)
490 : num_results_received_(0),
491 num_results_to_wait_for_(0),
492 waiting_for_result_(false),
493 profile_(profile),
494 captive_portal_service_(
495 CaptivePortalServiceFactory::GetForProfile(profile)),
496 captive_portal_result_(
497 captive_portal_service_->last_detection_result()) {
498 registrar_.Add(this,
499 chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT,
500 content::Source<Profile>(profile_));
501 }
502
503 void CaptivePortalObserver::WaitForResults(int num_results_to_wait_for) {
504 EXPECT_LT(0, num_results_to_wait_for);
505 EXPECT_FALSE(waiting_for_result_);
506 if (num_results_received_ < num_results_to_wait_for) {
507 num_results_to_wait_for_ = num_results_to_wait_for;
508 waiting_for_result_ = true;
509 ui_test_utils::RunMessageLoop();
510 EXPECT_FALSE(waiting_for_result_);
511 }
512 EXPECT_EQ(num_results_received_, num_results_to_wait_for);
513 }
514
515 void CaptivePortalObserver::Observe(
516 int type,
517 const content::NotificationSource& source,
518 const content::NotificationDetails& details) {
519 ASSERT_EQ(type, chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT);
520 ASSERT_EQ(profile_, content::Source<Profile>(source).ptr());
521
522 CaptivePortalService::Results* results =
523 content::Details<CaptivePortalService::Results>(details).ptr();
524
525 EXPECT_EQ(captive_portal_result_, results->previous_result);
526 EXPECT_EQ(captive_portal_service_->last_detection_result(),
527 results->result);
528
529 captive_portal_result_ = results->result;
530 ++num_results_received_;
531
532 if (waiting_for_result_ &&
533 num_results_to_wait_for_ == num_results_received_) {
534 waiting_for_result_ = false;
535 MessageLoop::current()->Quit();
536 }
537 }
538
539 } // namespace
540
541 class CaptivePortalBrowserTest : public InProcessBrowserTest {
542 public:
543 CaptivePortalBrowserTest();
544
545 // InProcessBrowserTest:
546 virtual void SetUpCommandLine(CommandLine* command_line) OVERRIDE;
547 virtual void SetUpOnMainThread() OVERRIDE;
548 virtual void CleanUpOnMainThread() OVERRIDE;
549
550 // Sets the captive portal checking preference. Does not affect the command
551 // line flag, which is set in SetUpCommandLine.
552 void EnableCaptivePortalDetection(Profile* profile, bool enabled);
553
554 // Sets up the captive portal service for the given profile so that
555 // all checks go to |test_url|. Also disables all timers.
556 void SetUpCaptivePortalService(Profile* profile, const GURL& test_url);
557
558 // Returns true if |browser|'s profile is currently running a captive portal
559 // check.
560 bool CheckPending(Browser* browser);
561
562 // Returns the CaptivePortalTabReloader::State of |tab_contents|.
563 CaptivePortalTabReloader::State GetStateOfTabReloader(
564 TabContentsWrapper* tab_contents) const;
565
566 // Returns the CaptivePortalTabReloader::State of the indicated tab.
567 CaptivePortalTabReloader::State GetStateOfTabReloaderAt(Browser* browser,
568 int index) const;
569
570 // Returns the number of tabs with the given state, across all profiles.
571 int NumTabsWithState(CaptivePortalTabReloader::State state) const;
572
573 // Returns the number of tabs broken by captive portals, across all profiles.
574 int NumBrokenTabs() const;
575
576 // Returns the number of tabs that need to be reloaded due to having logged
577 // in to a captive portal, across all profiles.
578 int NumNeedReloadTabs() const;
579
580 // Navigates |browser|'s active tab to |url| and expects no captive portal
581 // test to be triggered. |expected_navigations| is the number of times the
582 // active tab will end up being navigated. It should be 1, except for the
583 // Link Doctor page, which acts like two navigations.
584 void NavigateToPageExpectNoTest(Browser* browser,
585 const GURL& url,
586 int expected_navigations);
587
588 // Navigates |browser|'s active tab to an SSL tab that takes a while to load,
589 // triggering a captive portal check, which is expected to give the result
590 // |expected_result|. The page finishes loading, with a timeout, after the
591 // captive portal check.
592 void SlowLoadNoCaptivePortal(Browser* browser, Result expected_result);
593
594 // Navigates |browser|'s active tab to an SSL timeout, expecting a captive
595 // portal check to be triggered and return a result which will indicates
596 // there's no detected captive portal.
597 void FastTimeoutNoCaptivePortal(Browser* browser, Result expected_result);
598
599 // Navigates the active tab to a slow loading SSL page, which will then
600 // trigger a captive portal test. The test is expected to find a captive
601 // portal. The slow loading page will continue to load after the function
602 // returns, until URLRequestTimeoutOnDemandJob::FailRequests() is called,
603 // at which point it will timeout.
604 //
605 // When |expect_login_tab| is false, no login tab is expected to be opened,
606 // because one already exists, and the function returns once the captive
607 // portal test is complete.
608 //
609 // If |expect_login_tab| is true, a login tab is then expected to be opened.
610 // It waits until both the login tab has finished loading, and two captive
611 // portal tests complete. The second test is triggered by the load of the
612 // captive portal tab completing.
613 //
614 // This function must not be called when the active tab is currently loading.
615 void SlowLoadBehindCaptivePortal(Browser* browser, bool expect_login_tab);
616
617 // Just like SlowLoadBehindCaptivePortal, except the navigated tab has
618 // a connection timeout rather having its time trigger, and the function
619 // waits until that timeout occurs.
620 void FastTimeoutBehindCaptivePortal(Browser* browser,
621 bool expect_open_login_tab);
622
623 // Navigates the login tab without logging in. The login tab must be the
624 // specified browser's active tab. Expects no other tab to change state.
625 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
626 // that nothing has gone wrong prior to the function call.
627 void NavigateLoginTab(Browser* browser,
628 int num_loading_tabs,
629 int num_timed_out_tabs);
630
631 // Simulates a login by updating the URLRequestMockCaptivePortalJob's
632 // behind captive portal state, and navigating the login tab. Waits for
633 // all broken but not loading tabs to be reloaded.
634 // |num_loading_tabs| and |num_timed_out_tabs| are used as extra checks
635 // that nothing has gone wrong prior to the function call.
636 void Login(Browser* browser, int num_loading_tabs, int num_timed_out_tabs);
637
638 // Makes the slow SSL loads of all active tabs time out at once, and waits for
639 // them to finish both that load and the automatic reload it should trigger.
640 // There should be no timed out tabs when this is called. The former login
641 // tab should be the active tab.
642 void FailLoadsAfterLogin(Browser* browser, int num_loading_tabs);
643
644 // Makes the slow SSL loads of all active tabs time out at once, and waits for
645 // them to finish displaying their error pages. The login tab should be the
646 // active tab. There should be no timed out tabs when this is called.
647 void FailLoadsWithoutLogin(Browser* browser, int num_loading_tabs);
648
649 // Sets the timeout used by a CaptivePortalTabReloader on slow SSL loads
650 // before a captive portal check.
651 void SetSlowSSLLoadTime(CaptivePortalTabReloader* tab_reloader,
652 base::TimeDelta slow_ssl_load_time);
653
654 CaptivePortalTabReloader* GetTabReloader(
655 TabContentsWrapper* tab_contents) const;
656
657 private:
658 DISALLOW_COPY_AND_ASSIGN(CaptivePortalBrowserTest);
659 };
660
661 CaptivePortalBrowserTest::CaptivePortalBrowserTest() {
662 }
663
664 void CaptivePortalBrowserTest::SetUpOnMainThread() {
665 // Enable mock requests.
666 content::BrowserThread::PostTask(
667 content::BrowserThread::IO, FROM_HERE,
668 base::Bind(&chrome_browser_net::SetUrlRequestMocksEnabled, true));
669 URLRequestMockCaptivePortalJobFactory::AddUrlHandlers();
670
671 EnableCaptivePortalDetection(browser()->profile(), true);
672
673 // Set the captive portal service to use URLRequestMockCaptivePortalJob's
674 // mock URL, by default.
675 SetUpCaptivePortalService(browser()->profile(),
676 GURL(kMockCaptivePortalTestUrl));
677 }
678
679 void CaptivePortalBrowserTest::CleanUpOnMainThread() {
680 // No test should have a captive portal check pending on quit.
681 EXPECT_FALSE(CheckPending(browser()));
682 }
683
684 void CaptivePortalBrowserTest::SetUpCommandLine(
685 CommandLine* command_line) {
686 command_line->AppendSwitch(switches::kCaptivePortalDetection);
687 }
688
689 void CaptivePortalBrowserTest::EnableCaptivePortalDetection(
690 Profile* profile, bool enabled) {
691 profile->GetPrefs()->SetBoolean(prefs::kAlternateErrorPagesEnabled, enabled);
692 }
693
694 void CaptivePortalBrowserTest::SetUpCaptivePortalService(Profile* profile,
695 const GURL& test_url) {
696 CaptivePortalService* captive_portal_service =
697 CaptivePortalServiceFactory::GetForProfile(profile);
698 captive_portal_service->set_test_url(test_url);
699
700 // Don't use any non-zero timers. Timers are checked in unit tests.
701 CaptivePortalService::RecheckPolicy* recheck_policy =
702 &captive_portal_service->recheck_policy();
703 recheck_policy->initial_backoff_no_portal_ms = 0;
704 recheck_policy->initial_backoff_portal_ms = 0;
705 recheck_policy->backoff_policy.maximum_backoff_ms = 0;
706 }
707
708 bool CaptivePortalBrowserTest::CheckPending(Browser* browser) {
709 CaptivePortalService* captive_portal_service =
710 CaptivePortalServiceFactory::GetForProfile(browser->profile());
711
712 return captive_portal_service->FetchingURL() ||
713 captive_portal_service->TimerRunning();
714 }
715
716 CaptivePortalTabReloader::State
717 CaptivePortalBrowserTest::GetStateOfTabReloader(
718 TabContentsWrapper* tab_contents) const {
719 return GetTabReloader(tab_contents)->state();
720 }
721
722 CaptivePortalTabReloader::State
723 CaptivePortalBrowserTest::GetStateOfTabReloaderAt(
724 Browser* browser,
725 int index) const {
726 return GetStateOfTabReloader(browser->GetTabContentsWrapperAt(index));
727 }
728
729 int CaptivePortalBrowserTest::NumTabsWithState(
730 CaptivePortalTabReloader::State state) const {
731 int num_tabs = 0;
732 for (TabContentsIterator tab_contents_it;
733 !tab_contents_it.done();
734 ++tab_contents_it) {
735 if (GetStateOfTabReloader(*tab_contents_it) == state)
736 ++num_tabs;
737 }
738 return num_tabs;
739 }
740
741 int CaptivePortalBrowserTest::NumBrokenTabs() const {
742 return NumTabsWithState(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL);
743 }
744
745 int CaptivePortalBrowserTest::NumNeedReloadTabs() const {
746 return NumTabsWithState(CaptivePortalTabReloader::STATE_NEEDS_RELOAD);
747 }
748
749 void CaptivePortalBrowserTest::NavigateToPageExpectNoTest(
750 Browser* browser,
751 const GURL& url,
752 int expected_navigations) {
753 MultiNavigationObserver navigation_observer;
754 CaptivePortalObserver portal_observer(browser->profile());
755
756 ui_test_utils::NavigateToURLBlockUntilNavigationsComplete(
757 browser, url, expected_navigations);
758
759 // No captive portal checks should have ocurred or be pending, and there
760 // should be no new tabs.
761 EXPECT_EQ(0, portal_observer.num_results_received());
762 EXPECT_FALSE(CheckPending(browser));
763 EXPECT_EQ(1, browser->tab_count());
764 EXPECT_EQ(expected_navigations, navigation_observer.num_navigations());
765 EXPECT_EQ(0, NumLoadingTabs());
766 }
767
768 void CaptivePortalBrowserTest::SlowLoadNoCaptivePortal(
769 Browser* browser, Result expected_result) {
770 CaptivePortalTabReloader* tab_reloader =
771 GetTabReloader(browser->GetSelectedTabContentsWrapper());
772 ASSERT_TRUE(tab_reloader);
773 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
774
775 MultiNavigationObserver navigation_observer;
776 CaptivePortalObserver portal_observer(browser->profile());
777 ui_test_utils::NavigateToURLWithDisposition(browser,
778 GURL(kMockHttpsUrl),
779 CURRENT_TAB,
780 ui_test_utils::BROWSER_TEST_NONE);
781
782 portal_observer.WaitForResults(1);
783
784 ASSERT_EQ(1, browser->tab_count());
785 EXPECT_EQ(expected_result, portal_observer.captive_portal_result());
786 EXPECT_EQ(1, portal_observer.num_results_received());
787 EXPECT_EQ(0, navigation_observer.num_navigations());
788 EXPECT_FALSE(CheckPending(browser));
789
790 // First tab should still be loading.
791 EXPECT_EQ(1, NumLoadingTabs());
792
793 // Original request times out.
794 URLRequestTimeoutOnDemandJob::FailRequests();
795 navigation_observer.WaitForNavigations(1);
796
797 ASSERT_EQ(1, browser->tab_count());
798 EXPECT_EQ(1, portal_observer.num_results_received());
799 EXPECT_FALSE(CheckPending(browser));
800 EXPECT_EQ(0, NumLoadingTabs());
801
802 // Set a slow SSL load time to prevent the timer from triggering.
803 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
804 }
805
806 void CaptivePortalBrowserTest::FastTimeoutNoCaptivePortal(
807 Browser* browser, Result expected_result) {
808 ASSERT_NE(expected_result, RESULT_BEHIND_CAPTIVE_PORTAL);
809
810 // Set the load time to be large, so the timer won't trigger. The value is
811 // not restored at the end of the function.
812 CaptivePortalTabReloader* tab_reloader =
813 GetTabReloader(browser->GetSelectedTabContentsWrapper());
814 ASSERT_TRUE(tab_reloader);
815 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
816
817 MultiNavigationObserver navigation_observer;
818 CaptivePortalObserver portal_observer(browser->profile());
819
820 // Neither of these should be changed by the navigation.
821 int active_index = browser->active_index();
822 int expected_tab_count = browser->tab_count();
823
824 ui_test_utils::NavigateToURL(
825 browser,
826 URLRequestFailedJob::GetMockHttpsUrl(net::ERR_CONNECTION_TIMED_OUT));
827
828 // An attempt to detect a captive portal should have started by now. If not,
829 // abort early to prevent hanging.
830 ASSERT_TRUE(portal_observer.num_results_received() > 0 ||
831 CheckPending(browser));
832
833 portal_observer.WaitForResults(1);
834 navigation_observer.WaitForNavigations(1);
835
836 // Check the result.
837 EXPECT_EQ(1, portal_observer.num_results_received());
838 EXPECT_EQ(expected_result, portal_observer.captive_portal_result());
839
840 // Check that the right tab was navigated, and there were no extra
841 // navigations.
842 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
843 browser->GetWebContentsAt(active_index)));
844 EXPECT_EQ(0, NumLoadingTabs());
845
846 // Check the tab's state, and verify no captive portal check is pending.
847 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
848 GetStateOfTabReloaderAt(browser, 0));
849 EXPECT_FALSE(CheckPending(browser));
850
851 // Make sure no login tab was opened.
852 EXPECT_EQ(expected_tab_count, browser->tab_count());
853 }
854
855 void CaptivePortalBrowserTest::SlowLoadBehindCaptivePortal(
856 Browser* browser,
857 bool expect_open_login_tab) {
858 // Calling this on a tab that's waiting for a load to manually be timed out
859 // will result in a hang.
860 ASSERT_FALSE(browser->GetSelectedWebContents()->IsLoading());
861
862 // Trigger a captive portal check quickly.
863 CaptivePortalTabReloader* tab_reloader =
864 GetTabReloader(browser->GetSelectedTabContentsWrapper());
865 ASSERT_TRUE(tab_reloader);
866 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
867
868 // Number of tabs expected to be open after the captive portal checks
869 // have completed.
870 int initial_tab_count = browser->tab_count();
871 int initial_active_index = browser->active_index();
872 int initial_loading_tabs = NumLoadingTabs();
873 int expected_broken_tabs = NumBrokenTabs();
874 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
875 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())) {
876 ++expected_broken_tabs;
877 }
878
879 MultiNavigationObserver navigation_observer;
880 CaptivePortalObserver portal_observer(browser->profile());
881 ui_test_utils::NavigateToURLWithDisposition(browser,
882 GURL(kMockHttpsUrl),
883 CURRENT_TAB,
884 ui_test_utils::BROWSER_TEST_NONE);
885
886 if (expect_open_login_tab) {
887 portal_observer.WaitForResults(2);
888 navigation_observer.WaitForNavigations(1);
889 EXPECT_EQ(2, portal_observer.num_results_received());
890
891 ASSERT_EQ(initial_tab_count + 1, browser->tab_count());
892 EXPECT_EQ(initial_tab_count, browser->active_index());
893
894 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
895 browser->GetWebContentsAt(initial_tab_count)));
896 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
897 GetStateOfTabReloader(browser->GetTabContentsWrapperAt(1)));
898 EXPECT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(1)));
899 } else {
900 portal_observer.WaitForResults(1);
901 EXPECT_EQ(0, navigation_observer.num_navigations());
902 EXPECT_EQ(initial_active_index, browser->active_index());
903 ASSERT_EQ(initial_tab_count, browser->tab_count());
904 EXPECT_EQ(initial_active_index, browser->active_index());
905 }
906
907 EXPECT_EQ(initial_loading_tabs + 1, NumLoadingTabs());
908 EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
909 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
910 portal_observer.captive_portal_result());
911 EXPECT_FALSE(CheckPending(browser));
912
913 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
914 GetStateOfTabReloader(
915 browser->GetTabContentsWrapperAt(initial_active_index)));
916
917 // Reset the load time to be large, so the timer won't trigger on a reload.
918 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
919 }
920
921 void CaptivePortalBrowserTest::FastTimeoutBehindCaptivePortal(
922 Browser* browser,
923 bool expect_open_login_tab) {
924 // Calling this on a tab that's waiting for a load to manually be timed out
925 // will result in a hang.
926 ASSERT_FALSE(browser->GetSelectedWebContents()->IsLoading());
927
928 // Set the load time to be large, so the timer won't trigger. The value is
929 // not restored at the end of the function.
930 CaptivePortalTabReloader* tab_reloader =
931 GetTabReloader(browser->GetSelectedTabContentsWrapper());
932 ASSERT_TRUE(tab_reloader);
933 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromHours(1));
934
935 // Number of tabs expected to be open after the captive portal checks
936 // have completed.
937 int initial_tab_count = browser->tab_count();
938 int initial_active_index = browser->active_index();
939 int initial_loading_tabs = NumLoadingTabs();
940 int expected_broken_tabs = NumBrokenTabs();
941 if (CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL !=
942 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper())) {
943 ++expected_broken_tabs;
944 }
945
946 MultiNavigationObserver navigation_observer;
947 CaptivePortalObserver portal_observer(browser->profile());
948 ui_test_utils::NavigateToURLWithDisposition(browser,
949 GURL(kMockHttpsQuickTimeoutUrl),
950 CURRENT_TAB,
951 ui_test_utils::BROWSER_TEST_NONE);
952
953 if (expect_open_login_tab) {
954 portal_observer.WaitForResults(2);
955 navigation_observer.WaitForNavigations(2);
956 EXPECT_EQ(2, portal_observer.num_results_received());
957
958 ASSERT_EQ(initial_tab_count + 1, browser->tab_count());
959 EXPECT_EQ(initial_tab_count, browser->active_index());
960 // Make sure that the originally active tab and the captive portal tab have
961 // each loaded once.
962 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
963 browser->GetWebContentsAt(initial_active_index)));
964 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
965 browser->GetWebContentsAt(initial_tab_count)));
966 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
967 GetStateOfTabReloader(browser->GetTabContentsWrapperAt(1)));
968 EXPECT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(1)));
969 } else {
970 portal_observer.WaitForResults(1);
971 navigation_observer.WaitForNavigations(1);
972 EXPECT_EQ(1, portal_observer.num_results_received());
973
974 EXPECT_EQ(initial_active_index, browser->active_index());
975 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
976 browser->GetWebContentsAt(initial_active_index)));
977 ASSERT_EQ(initial_tab_count, browser->tab_count());
978 EXPECT_EQ(initial_active_index, browser->active_index());
979 }
980
981 EXPECT_EQ(initial_loading_tabs, NumLoadingTabs());
982 EXPECT_EQ(expected_broken_tabs, NumBrokenTabs());
983 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
984 portal_observer.captive_portal_result());
985 EXPECT_FALSE(CheckPending(browser));
986
987 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
988 GetStateOfTabReloader(
989 browser->GetTabContentsWrapperAt(initial_active_index)));
990 }
991
992 void CaptivePortalBrowserTest::NavigateLoginTab(Browser* browser,
993 int num_loading_tabs,
994 int num_timed_out_tabs) {
995 MultiNavigationObserver navigation_observer;
996 CaptivePortalObserver portal_observer(browser->profile());
997
998 int initial_tab_count = browser->tab_count();
999 EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
1000 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
1001
1002 int login_tab_index = browser->active_index();
1003 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1004 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper()));
1005 ASSERT_TRUE(IsLoginTab(browser->GetSelectedTabContentsWrapper()));
1006
1007 // Do the navigation.
1008 content::RenderViewHost* render_view_host =
1009 browser->GetSelectedWebContents()->GetRenderViewHost();
1010 render_view_host->ExecuteJavascriptInWebFrame(
1011 string16(),
1012 ASCIIToUTF16("submitForm()"));
1013
1014 portal_observer.WaitForResults(1);
1015 navigation_observer.WaitForNavigations(1);
1016
1017 // Check the captive portal result.
1018 EXPECT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
1019 portal_observer.captive_portal_result());
1020 EXPECT_EQ(1, portal_observer.num_results_received());
1021 EXPECT_FALSE(CheckPending(browser));
1022
1023 // Make sure not much has changed.
1024 EXPECT_EQ(initial_tab_count, browser->tab_count());
1025 EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
1026 EXPECT_EQ(num_loading_tabs + num_timed_out_tabs, NumBrokenTabs());
1027 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1028 GetStateOfTabReloader(browser->GetTabContentsWrapperAt(
1029 login_tab_index)));
1030 EXPECT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(login_tab_index)));
1031
1032 // Make sure there were no unexpected navigations.
1033 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1034 browser->GetWebContentsAt(login_tab_index)));
1035 }
1036
1037 void CaptivePortalBrowserTest::Login(Browser* browser,
1038 int num_loading_tabs,
1039 int num_timed_out_tabs) {
1040 // Simulate logging in.
1041 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1042
1043 MultiNavigationObserver navigation_observer;
1044 CaptivePortalObserver portal_observer(browser->profile());
1045
1046 int initial_tab_count = browser->tab_count();
1047 ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
1048 EXPECT_EQ(num_timed_out_tabs, NumBrokenTabs() - NumLoadingTabs());
1049
1050 // Verify that the login page is on top.
1051 int login_tab_index = browser->active_index();
1052 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1053 GetStateOfTabReloader(browser->GetTabContentsWrapperAt(
1054 login_tab_index)));
1055 ASSERT_TRUE(IsLoginTab(browser->GetTabContentsWrapperAt(login_tab_index)));
1056
1057 // Trigger a navigation.
1058 content::RenderViewHost* render_view_host =
1059 browser->GetSelectedWebContents()->GetRenderViewHost();
1060 render_view_host->ExecuteJavascriptInWebFrame(
1061 string16(),
1062 ASCIIToUTF16("submitForm()"));
1063
1064 portal_observer.WaitForResults(1);
1065
1066 // Wait for all the timed out tabs to reload.
1067 navigation_observer.WaitForNavigations(1 + num_timed_out_tabs);
1068 EXPECT_EQ(1, portal_observer.num_results_received());
1069
1070 // The tabs that were loading before should still be loading, and now be in
1071 // STATE_NEEDS_RELOAD.
1072 EXPECT_EQ(0, NumBrokenTabs());
1073 EXPECT_EQ(num_loading_tabs, NumLoadingTabs());
1074 EXPECT_EQ(num_loading_tabs, NumNeedReloadTabs());
1075
1076 // Make sure that the broken tabs have reloaded, and there's no more
1077 // captive portal tab.
1078 EXPECT_EQ(initial_tab_count, browser->tab_count());
1079 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1080 GetStateOfTabReloaderAt(browser, login_tab_index));
1081 EXPECT_FALSE(IsLoginTab(browser->GetTabContentsWrapperAt(login_tab_index)));
1082
1083 // Make sure there were no unexpected navigations of the login tab.
1084 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1085 browser->GetWebContentsAt(login_tab_index)));
1086 }
1087
1088 void CaptivePortalBrowserTest::FailLoadsAfterLogin(Browser* browser,
1089 int num_loading_tabs) {
1090 ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
1091 ASSERT_EQ(num_loading_tabs, NumNeedReloadTabs());
1092 EXPECT_EQ(0, NumBrokenTabs());
1093
1094 int initial_num_tabs = browser->tab_count();
1095 int initial_active_tab = browser->active_index();
1096
1097 CaptivePortalObserver portal_observer(browser->profile());
1098 MultiNavigationObserver navigation_observer;
1099 // Connection finally times out.
1100 URLRequestTimeoutOnDemandJob::FailRequests();
1101
1102 navigation_observer.WaitForNavigations(2 * num_loading_tabs);
1103
1104 // No captive portal checks should have ocurred or be pending, and there
1105 // should be no new tabs.
1106 EXPECT_EQ(0, portal_observer.num_results_received());
1107 EXPECT_FALSE(CheckPending(browser));
1108 EXPECT_EQ(initial_num_tabs, browser->tab_count());
1109
1110 EXPECT_EQ(initial_active_tab, browser->active_index());
1111
1112 EXPECT_EQ(0, NumNeedReloadTabs());
1113 EXPECT_EQ(0, NumLoadingTabs());
1114 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
1115 browser->GetSelectedWebContents()));
1116 }
1117
1118 void CaptivePortalBrowserTest::FailLoadsWithoutLogin(Browser* browser,
1119 int num_loading_tabs) {
1120 ASSERT_EQ(num_loading_tabs, NumLoadingTabs());
1121 ASSERT_EQ(0, NumNeedReloadTabs());
1122 EXPECT_EQ(num_loading_tabs, NumBrokenTabs());
1123
1124 int initial_num_tabs = browser->tab_count();
1125 int login_tab = browser->active_index();
1126 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1127 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper()));
1128 ASSERT_TRUE(IsLoginTab(browser->GetSelectedTabContentsWrapper()));
1129
1130 CaptivePortalObserver portal_observer(browser->profile());
1131 MultiNavigationObserver navigation_observer;
1132 // Connection finally times out.
1133 URLRequestTimeoutOnDemandJob::FailRequests();
1134
1135 navigation_observer.WaitForNavigations(num_loading_tabs);
1136
1137 // No captive portal checks should have ocurred or be pending, and there
1138 // should be no new tabs.
1139 EXPECT_EQ(0, portal_observer.num_results_received());
1140 EXPECT_FALSE(CheckPending(browser));
1141 EXPECT_EQ(initial_num_tabs, browser->tab_count());
1142
1143 EXPECT_EQ(0, NumNeedReloadTabs());
1144 EXPECT_EQ(0, NumLoadingTabs());
1145 EXPECT_EQ(num_loading_tabs, NumBrokenTabs());
1146 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1147 GetStateOfTabReloader(browser->GetSelectedTabContentsWrapper()));
1148 EXPECT_TRUE(IsLoginTab(browser->GetSelectedTabContentsWrapper()));
1149 EXPECT_EQ(login_tab, browser->active_index());
1150
1151 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
1152 browser->GetWebContentsAt(login_tab)));
1153 }
1154
1155 void CaptivePortalBrowserTest::SetSlowSSLLoadTime(
1156 CaptivePortalTabReloader* tab_reloader,
1157 base::TimeDelta slow_ssl_load_time) {
1158 tab_reloader->set_slow_ssl_load_time(slow_ssl_load_time);
1159 }
1160
1161 CaptivePortalTabReloader* CaptivePortalBrowserTest::GetTabReloader(
1162 TabContentsWrapper* tab_contents) const {
1163 return tab_contents->captive_portal_tab_helper()->GetTabReloaderForTest();
1164 }
1165
1166 // Make sure there's no test for a captive portal on HTTP timeouts. This will
1167 // also trigger the link doctor page, which results in the load of a second
1168 // error page.
1169 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpTimeout) {
1170 GURL url = URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_TIMED_OUT);
1171 NavigateToPageExpectNoTest(browser(), url, 2);
1172 }
1173
1174 // Make sure there's no check for a captive portal on HTTPS errors other than
1175 // timeouts, when they preempt the slow load timer.
1176 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsNonTimeoutError) {
1177 GURL url = URLRequestFailedJob::GetMockHttpsUrl(net::ERR_UNEXPECTED);
1178 NavigateToPageExpectNoTest(browser(), url, 1);
1179 }
1180
1181 // Make sure no captive portal test triggers on HTTPS timeouts of iframes.
1182 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, HttpsIframeTimeout) {
1183 CaptivePortalObserver portal_observer(browser()->profile());
1184
1185 // Use an HTTPS server for the top level page.
1186 net::TestServer https_server(net::TestServer::TYPE_HTTPS,
1187 net::TestServer::kLocalhost,
1188 FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1189 ASSERT_TRUE(https_server.Start());
1190
1191 GURL url = https_server.GetURL(kTestServerIframeTimeoutPath);
1192 NavigateToPageExpectNoTest(browser(), url, 1);
1193 }
1194
1195 // Check the captive portal result when the test request reports a network
1196 // error. The check is triggered by a slow loading page, and the page
1197 // errors out only after getting a captive portal result.
1198 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFails) {
1199 SetUpCaptivePortalService(
1200 browser()->profile(),
1201 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED));
1202 SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE);
1203 }
1204
1205 // Same as above, but for the rather unlikely case that the connection times out
1206 // before the timer triggers.
1207 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RequestFailsFastTimout) {
1208 SetUpCaptivePortalService(
1209 browser()->profile(),
1210 URLRequestFailedJob::GetMockHttpUrl(net::ERR_CONNECTION_CLOSED));
1211 FastTimeoutNoCaptivePortal(browser(), RESULT_NO_RESPONSE);
1212 }
1213
1214 // Checks the case that captive portal detection is disabled.
1215 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Disabled) {
1216 EnableCaptivePortalDetection(browser()->profile(), false);
1217 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED);
1218 }
1219
1220 // Checks that we look for a captive portal on HTTPS timeouts and don't reload
1221 // the error tab when the captive portal probe gets a 204 response, indicating
1222 // there is no captive portal.
1223 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, InternetConnected) {
1224 // Can't just use SetBehindCaptivePortal(false), since then there wouldn't
1225 // be a timeout.
1226 ASSERT_TRUE(test_server()->Start());
1227 SetUpCaptivePortalService(browser()->profile(),
1228 test_server()->GetURL("nocontent"));
1229 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED);
1230 }
1231
1232 // Checks that no login page is opened when the HTTP test URL redirects to an
1233 // SSL certificate error.
1234 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, RedirectSSLCertError) {
1235 // Need an HTTP TestServer to handle a dynamically created server redirect.
1236 ASSERT_TRUE(test_server()->Start());
1237
1238 net::TestServer::HTTPSOptions https_options;
1239 https_options.server_certificate =
1240 net::TestServer::HTTPSOptions::CERT_MISMATCHED_NAME;
1241 net::TestServer https_server(https_options,
1242 FilePath(FILE_PATH_LITERAL("chrome/test/data")));
1243 ASSERT_TRUE(https_server.Start());
1244
1245 GURL ssl_login_url = https_server.GetURL(kTestServerLoginPath);
1246
1247 CaptivePortalService* captive_portal_service =
1248 CaptivePortalServiceFactory::GetForProfile(browser()->profile());
1249 ASSERT_TRUE(captive_portal_service);
1250 SetUpCaptivePortalService(
1251 browser()->profile(),
1252 test_server()->GetURL(CreateServerRedirect(ssl_login_url.spec())));
1253
1254 SlowLoadNoCaptivePortal(browser(), RESULT_NO_RESPONSE);
1255 }
1256
1257 // A slow SSL load triggers a captive portal check. The user logs on before
1258 // the SSL page times out. We wait for the timeout and subsequent reload.
1259 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, Login) {
1260 // Load starts, detect captive portal and open up a login tab.
1261 SlowLoadBehindCaptivePortal(browser(), true);
1262
1263 // Log in. One loading tab, no timed out ones.
1264 Login(browser(), 1, 0);
1265
1266 string16 expected_title = ASCIIToUTF16(kInternetConnectedTitle);
1267 ui_test_utils::TitleWatcher title_watcher(
1268 browser()->GetWebContentsAt(0),
1269 expected_title);
1270
1271 // Timeout occurs, and page is automatically reloaded.
1272 FailLoadsAfterLogin(browser(), 1);
1273
1274 // Double check the tab's title.
1275 EXPECT_EQ(expected_title, title_watcher.WaitAndGetTitle());
1276 }
1277
1278 // Same as above, except we make sure everything works with an incognito
1279 // profile. Main issues it tests for are that the incognito has its own
1280 // non-NULL captive portal service, and we open the tab in the correct
1281 // window.
1282 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginIncognito) {
1283 // This will watch tabs for both profiles, but only used to make sure no
1284 // navigations occur for the non-incognito profile.
1285 MultiNavigationObserver navigation_observer;
1286 CaptivePortalObserver non_incognito_portal_observer(browser()->profile());
1287
1288 Browser* incognito_browser = CreateIncognitoBrowser();
1289 EnableCaptivePortalDetection(incognito_browser->profile(), true);
1290 SetUpCaptivePortalService(incognito_browser->profile(),
1291 GURL(kMockCaptivePortalTestUrl));
1292
1293 SlowLoadBehindCaptivePortal(incognito_browser, true);
1294
1295 EXPECT_EQ(1, browser()->tab_count());
1296 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1297 GetStateOfTabReloaderAt(browser(), 0));
1298
1299 Login(incognito_browser, 1, 0);
1300 FailLoadsAfterLogin(incognito_browser, 1);
1301
1302 EXPECT_EQ(1, browser()->tab_count());
1303 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1304 GetStateOfTabReloaderAt(browser(), 0));
1305
1306 EXPECT_EQ(0, navigation_observer.NumNavigationsForTab(
1307 browser()->GetWebContentsAt(0)));
1308 EXPECT_EQ(0, non_incognito_portal_observer.num_results_received());
1309 }
1310
1311 // The captive portal page is opened before the SSL page times out,
1312 // but the user logs in only after the page times out.
1313 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginSlow) {
1314 SlowLoadBehindCaptivePortal(browser(), true);
1315 FailLoadsWithoutLogin(browser(), 1);
1316 Login(browser(), 0, 1);
1317 }
1318
1319 // Checks the unlikely case that the tab times out before the timer triggers.
1320 // This most likely won't happen, but should still work:
1321 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginFastTimeout) {
1322 FastTimeoutBehindCaptivePortal(browser(), true);
1323 Login(browser(), 0, 1);
1324 }
1325
1326 // Tries navigating both the tab that encounters an SSL timeout and the
1327 // login tab twice, only logging in the second time.
1328 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, LoginExtraNavigations) {
1329 FastTimeoutBehindCaptivePortal(browser(), true);
1330
1331 // Activate the timed out tab and navigate it to a timeout again.
1332 browser()->ActivateTabAt(0, true);
1333 FastTimeoutBehindCaptivePortal(browser(), false);
1334
1335 // Activate and navigate the captive portal tab. This should not trigger a
1336 // reload of the tab with the error.
1337 browser()->ActivateTabAt(1, true);
1338 NavigateLoginTab(browser(), 0, 1);
1339
1340 // Simulate logging in.
1341 Login(browser(), 0, 1);
1342 }
1343
1344 // After the first SSL timeout, closes the login tab and makes sure it's opened
1345 // it again on a second timeout.
1346 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, CloseLoginTab) {
1347 // First load starts, opens a login tab, and then times out.
1348 SlowLoadBehindCaptivePortal(browser(), true);
1349 FailLoadsWithoutLogin(browser(), 1);
1350
1351 // Close login tab.
1352 browser()->CloseTab();
1353
1354 // Go through the standard slow load login, and make sure it still works.
1355 SlowLoadBehindCaptivePortal(browser(), true);
1356 Login(browser(), 1, 0);
1357 FailLoadsAfterLogin(browser(), 1);
1358 }
1359
1360 // Checks that two tabs with SSL timeouts in the same window work. Both
1361 // tabs only timeout after logging in.
1362 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoBrokenTabs) {
1363 SlowLoadBehindCaptivePortal(browser(), true);
1364
1365 // Can't set the TabReloader HTTPS timeout on a new tab without doing some
1366 // acrobatics, so open a new tab at a normal page, and then navigate it to a
1367 // timeout.
1368 MultiNavigationObserver navigation_observer;
1369 CaptivePortalObserver portal_observer(browser()->profile());
1370 ui_test_utils::NavigateToURLWithDisposition(
1371 browser(),
1372 URLRequestMockHTTPJob::GetMockUrl(
1373 FilePath(FILE_PATH_LITERAL("title2.html"))),
1374 NEW_FOREGROUND_TAB,
1375 ui_test_utils::BROWSER_TEST_WAIT_FOR_NAVIGATION);
1376
1377 ASSERT_EQ(3, browser()->tab_count());
1378 EXPECT_FALSE(CheckPending(browser()));
1379 EXPECT_EQ(0, portal_observer.num_results_received());
1380 EXPECT_EQ(1, NumLoadingTabs());
1381 EXPECT_EQ(1, navigation_observer.num_navigations());
1382 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1383 browser()->GetWebContentsAt(2)));
1384 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
1385 GetStateOfTabReloaderAt(browser(), 0));
1386 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1387 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1)));
1388 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1)));
1389 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE,
1390 GetStateOfTabReloaderAt(browser(), 2));
1391 ASSERT_EQ(2, browser()->active_index());
1392
1393 SlowLoadBehindCaptivePortal(browser(), false);
1394
1395 browser()->ActivateTabAt(1, true);
1396 Login(browser(), 2, 0);
1397 FailLoadsAfterLogin(browser(), 2);
1398 }
1399
1400 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, AbortLoad) {
1401 // Go to the error page.
1402 SlowLoadBehindCaptivePortal(browser(), true);
1403 // The load will be destroyed without returning any result, so remove it from
1404 // the list of jobs that will timeout.
1405 URLRequestTimeoutOnDemandJob::AbandonRequests();
1406
1407 CaptivePortalObserver portal_observer(browser()->profile());
1408 MultiNavigationObserver navigation_observer;
1409
1410 // Switch back to the hung tab from the login tab, and abort the navigation.
1411 browser()->ActivateTabAt(0, true);
1412 browser()->Stop();
1413 navigation_observer.WaitForNavigations(1);
1414
1415 EXPECT_EQ(0, NumBrokenTabs());
1416 EXPECT_EQ(0, portal_observer.num_results_received());
1417 EXPECT_FALSE(CheckPending(browser()));
1418 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1419 GetStateOfTabReloaderAt(browser(), 0));
1420
1421 browser()->ActivateTabAt(1, true);
1422 Login(browser(), 0, 0);
1423 }
1424
1425 // Checks the case where the timed out tab is successfully navigated before
1426 // logging in.
1427 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, NavigateBrokenTab) {
1428 // Go to the error page.
1429 SlowLoadBehindCaptivePortal(browser(), true);
1430 FailLoadsWithoutLogin(browser(), 1);
1431
1432 // Navigate the error tab to a non-error page.
1433 browser()->ActivateTabAt(0, true);
1434 ui_test_utils::NavigateToURL(browser(),
1435 URLRequestMockHTTPJob::GetMockUrl(
1436 FilePath(FILE_PATH_LITERAL("title2.html"))));
1437 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1438 GetStateOfTabReloaderAt(browser(), 0));
1439
1440 // Simulate logging in.
1441 browser()->ActivateTabAt(1, true);
1442 Login(browser(), 0, 0);
1443 }
1444
1445 // Navigates a broken, but still loading, tab to another timeout before logging
1446 // in.
1447 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest,
1448 NavigateBrokenToTimeoutTabWhileLoading) {
1449 // Go to the error page.
1450 SlowLoadBehindCaptivePortal(browser(), true);
1451 URLRequestTimeoutOnDemandJob::AbandonRequests();
1452
1453 CaptivePortalTabReloader* tab_reloader =
1454 GetTabReloader(browser()->GetTabContentsWrapperAt(0));
1455 ASSERT_TRUE(tab_reloader);
1456 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
1457
1458 CaptivePortalObserver portal_observer(browser()->profile());
1459 MultiNavigationObserver navigation_observer;
1460
1461 // Navigate the error tab to a non-error page. Can't have ui_test_utils
1462 // do the navigation because it will wait for loading tabs to stop loading
1463 // before navigating.
1464 browser()->ActivateTabAt(0, true);
1465 browser()->OpenURL(content::OpenURLParams(GURL(kMockHttpsUrl),
1466 content::Referrer(),
1467 CURRENT_TAB,
1468 content::PAGE_TRANSITION_TYPED,
1469 false));
1470 navigation_observer.WaitForNavigations(1);
1471 portal_observer.WaitForResults(1);
1472 EXPECT_FALSE(CheckPending(browser()));
1473 EXPECT_EQ(1, NumLoadingTabs());
1474 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
1475 GetStateOfTabReloaderAt(browser(), 0));
1476 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1477 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1)));
1478 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1)));
1479
1480 // Simulate logging in.
1481 browser()->ActivateTabAt(1, true);
1482 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
1483 Login(browser(), 1, 0);
1484
1485 // Timeout occurs, and page is automatically reloaded.
1486 FailLoadsAfterLogin(browser(), 1);
1487 }
1488
1489 // Checks that navigating a timed out tab back clears its state.
1490 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBack) {
1491 // Navigate to a working page.
1492 ui_test_utils::NavigateToURL(
1493 browser(),
1494 URLRequestMockHTTPJob::GetMockUrl(
1495 FilePath(FILE_PATH_LITERAL("title2.html"))));
1496
1497 // Go to the error page.
1498 SlowLoadBehindCaptivePortal(browser(), true);
1499 FailLoadsWithoutLogin(browser(), 1);
1500
1501 CaptivePortalObserver portal_observer(browser()->profile());
1502 MultiNavigationObserver navigation_observer;
1503
1504 // Activate the error page tab again and go back.
1505 browser()->ActivateTabAt(0, true);
1506 browser()->GoBack(CURRENT_TAB);
1507 navigation_observer.WaitForNavigations(1);
1508
1509 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1510 browser()->GetWebContentsAt(0)));
1511 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1512 GetStateOfTabReloaderAt(browser(), 0));
1513 EXPECT_EQ(0, portal_observer.num_results_received());
1514 }
1515
1516 // Checks that navigating back to a timeout triggers captive portal detection.
1517 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, GoBackToTimeout) {
1518 // Disable captive portal detection so the first navigation doesn't open a
1519 // login tab.
1520 EnableCaptivePortalDetection(browser()->profile(), false);
1521
1522 SlowLoadNoCaptivePortal(browser(), RESULT_INTERNET_CONNECTED);
1523
1524 // Navigate to a working page.
1525 ui_test_utils::NavigateToURL(browser(),
1526 URLRequestMockHTTPJob::GetMockUrl(
1527 FilePath(FILE_PATH_LITERAL("title2.html"))));
1528 ASSERT_EQ(CaptivePortalTabReloader::STATE_NONE,
1529 GetStateOfTabReloaderAt(browser(), 0));
1530
1531 EnableCaptivePortalDetection(browser()->profile(), true);
1532
1533 CaptivePortalTabReloader* tab_reloader =
1534 GetTabReloader(browser()->GetSelectedTabContentsWrapper());
1535 ASSERT_TRUE(tab_reloader);
1536 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
1537
1538 // Go to the error page.
1539 MultiNavigationObserver navigation_observer;
1540 CaptivePortalObserver portal_observer(browser()->profile());
1541 browser()->GoBack(CURRENT_TAB);
1542
1543 // Wait for both the check triggered by the broken tab and the first load
1544 // of the login tab, and for the login tab to stop loading.
1545 portal_observer.WaitForResults(2);
1546 navigation_observer.WaitForNavigations(1);
1547
1548 EXPECT_EQ(2, portal_observer.num_results_received());
1549 ASSERT_FALSE(CheckPending(browser()));
1550 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
1551 portal_observer.captive_portal_result());
1552
1553 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
1554 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(0)));
1555 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1556 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1)));
1557 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1)));
1558
1559 ASSERT_EQ(2, browser()->tab_count());
1560 EXPECT_EQ(1, browser()->active_index());
1561 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1562 browser()->GetWebContentsAt(1)));
1563 EXPECT_EQ(1, NumLoadingTabs());
1564
1565 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
1566 Login(browser(), 1, 0);
1567 FailLoadsAfterLogin(browser(), 1);
1568 }
1569
1570 // Checks that reloading a timeout triggers captive portal detection.
1571 // Much like the last test, though the captive portal is disabled before
1572 // the inital navigation, rather than captive portal detection.
1573 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, ReloadTimeout) {
1574 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(false);
1575
1576 // Do the first navigation while not behind a captive portal.
1577 CaptivePortalObserver portal_observer(browser()->profile());
1578 ui_test_utils::NavigateToURL(browser(), GURL(kMockHttpsUrl));
1579 ASSERT_EQ(0, portal_observer.num_results_received());
1580 ASSERT_EQ(1, browser()->tab_count());
1581
1582 // A captive portal spontaneously appears.
1583 URLRequestMockCaptivePortalJobFactory::SetBehindCaptivePortal(true);
1584
1585 CaptivePortalTabReloader* tab_reloader =
1586 GetTabReloader(browser()->GetSelectedTabContentsWrapper());
1587 ASSERT_TRUE(tab_reloader);
1588 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta());
1589
1590 MultiNavigationObserver navigation_observer;
1591 browser()->GetSelectedWebContents()->GetController().Reload(true);
1592
1593 // Wait for the login tab to open, and the two captive portal results from
1594 // opening an it.
1595 portal_observer.WaitForResults(2);
1596 navigation_observer.WaitForNavigations(1);
1597
1598 ASSERT_EQ(2, portal_observer.num_results_received());
1599 ASSERT_FALSE(CheckPending(browser()));
1600 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
1601 portal_observer.captive_portal_result());
1602
1603 ASSERT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
1604 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(0)));
1605 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1606 GetStateOfTabReloader(browser()->GetTabContentsWrapperAt(1)));
1607 ASSERT_TRUE(IsLoginTab(browser()->GetTabContentsWrapperAt(1)));
1608
1609 ASSERT_EQ(2, browser()->tab_count());
1610 EXPECT_EQ(1, browser()->active_index());
1611 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1612 browser()->GetWebContentsAt(1)));
1613 EXPECT_EQ(1, NumLoadingTabs());
1614
1615 SetSlowSSLLoadTime(tab_reloader, base::TimeDelta::FromDays(1));
1616 Login(browser(), 1, 0);
1617 FailLoadsAfterLogin(browser(), 1);
1618 }
1619
1620 // Checks the case where there are two windows, and there's an SSL timeout in
1621 // the background one.
1622 IN_PROC_BROWSER_TEST_F(CaptivePortalBrowserTest, TwoWindows) {
1623 Browser* browser2 = Browser::Create(browser()->profile());
1624 // Navigate the new browser window so it'll be shown and we can pick the
1625 // active window.
1626 ui_test_utils::NavigateToURL(browser2, GURL(chrome::kAboutBlankURL));
1627
1628 // Generally, |browser2| will be the active window. However, if the
1629 // original browser window lost focus before creating the new one, such as
1630 // when running multiple tests at once, the original browser window may
1631 // remain the profile's active window.
1632 Browser* active_browser =
1633 browser::FindTabbedBrowser(browser()->profile(), true);
1634 Browser* inactive_browser;
1635 if (active_browser == browser2) {
1636 // When only one test is running at a time, the new browser will probably be
1637 // on top, but when multiple tests are running at once, this is not
1638 // guaranteed.
1639 inactive_browser = browser();
1640 } else {
1641 ASSERT_EQ(active_browser, browser());
1642 inactive_browser = browser2;
1643 }
1644
1645 CaptivePortalObserver portal_observer(browser()->profile());
1646 MultiNavigationObserver navigation_observer;
1647
1648 // Navigate the tab in the inactive browser to an SSL timeout. Have to use
1649 // browser::NavigateParams and NEW_BACKGROUND_TAB to avoid activating the
1650 // window.
1651 browser::NavigateParams params(inactive_browser,
1652 GURL(kMockHttpsQuickTimeoutUrl),
1653 content::PAGE_TRANSITION_TYPED);
1654 params.disposition = NEW_BACKGROUND_TAB;
1655 params.window_action = browser::NavigateParams::NO_ACTION;
1656 ui_test_utils::NavigateToURL(&params);
1657 navigation_observer.WaitForNavigations(2);
1658
1659 // Make sure the active window hasn't changed, and its new tab is
1660 // active.
1661 ASSERT_EQ(active_browser,
1662 browser::FindTabbedBrowser(browser()->profile(), true));
1663 ASSERT_EQ(1, active_browser->active_index());
1664
1665 // Check that the only two navigated tabs were the new error tab in the
1666 // backround windows, and the login tab in the active window.
1667 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1668 inactive_browser->GetWebContentsAt(1)));
1669 EXPECT_EQ(1, navigation_observer.NumNavigationsForTab(
1670 active_browser->GetWebContentsAt(1)));
1671 EXPECT_EQ(0, NumLoadingTabs());
1672
1673 // Check captive portal test results.
1674 portal_observer.WaitForResults(2);
1675 ASSERT_EQ(RESULT_BEHIND_CAPTIVE_PORTAL,
1676 portal_observer.captive_portal_result());
1677 EXPECT_EQ(2, portal_observer.num_results_received());
1678
1679 // Check the inactive browser.
1680 EXPECT_EQ(2, inactive_browser->tab_count());
1681 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1682 GetStateOfTabReloaderAt(inactive_browser, 0));
1683 EXPECT_EQ(CaptivePortalTabReloader::STATE_BROKEN_BY_PORTAL,
1684 GetStateOfTabReloaderAt(inactive_browser, 1));
1685
1686 // Check the active browser.
1687 ASSERT_EQ(2, active_browser->tab_count());
1688 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1689 GetStateOfTabReloaderAt(active_browser, 0));
1690 EXPECT_EQ(CaptivePortalTabReloader::STATE_NONE,
1691 GetStateOfTabReloaderAt(active_browser, 1));
1692 EXPECT_TRUE(IsLoginTab(active_browser->GetTabContentsWrapperAt(1)));
1693
1694 // Simulate logging in.
1695 Login(active_browser, 0, 1);
1696 }
1697
1698 } // namespace captive_portal
OLDNEW
« no previous file with comments | « build/common.gypi ('k') | chrome/browser/captive_portal/captive_portal_login_detector.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698