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

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

Powered by Google App Engine
This is Rietveld 408576698