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

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

Powered by Google App Engine
This is Rietveld 408576698