|
OLD | NEW |
---|---|
(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(¶ms); | |
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 | |
OLD | NEW |