1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/captive_portal/captive_portal_tab_helper.h"
7 #include "base/callback.h"
8 #include "base/memory/scoped_ptr.h"
9 #include "chrome/browser/captive_portal/captive_portal_service.h"
10 #include "chrome/browser/captive_portal/captive_portal_tab_reloader.h"
11 #include "chrome/browser/chrome_notification_types.h"
12 #include "chrome/test/base/chrome_render_view_host_test_harness.h"
13 #include "content/public/browser/notification_details.h"
14 #include "content/public/browser/notification_service.h"
15 #include "content/public/browser/notification_source.h"
16 #include "content/public/browser/notification_types.h"
17 #include "content/public/browser/render_view_host.h"
18 #include "content/public/browser/render_process_host.h"
19 #include "content/public/browser/web_contents.h"
20 #include "content/public/test/test_renderer_host.h"
21 #include "content/public/test/web_contents_tester.h"
22 #include "net/base/net_errors.h"
23 #include "testing/gmock/include/gmock/gmock.h"
24 #include "testing/gtest/include/gtest/gtest.h"
26 using captive_portal::CaptivePortalResult
;
27 using content::ResourceType
;
31 const char* const kHttpUrl
= "http://whatever.com/";
32 const char* const kHttpsUrl
= "https://whatever.com/";
34 // Used for cross-process navigations. Shouldn't actually matter whether this
35 // is different from kHttpsUrl, but best to keep things consistent.
36 const char* const kHttpsUrl2
= "https://cross_process.com/";
38 // Some navigations behave differently depending on if they're cross-process
47 class MockCaptivePortalTabReloader
: public CaptivePortalTabReloader
{
49 MockCaptivePortalTabReloader()
50 : CaptivePortalTabReloader(NULL
, NULL
, base::Callback
<void()>()) {
53 MOCK_METHOD1(OnLoadStart
, void(bool));
54 MOCK_METHOD1(OnLoadCommitted
, void(int));
55 MOCK_METHOD0(OnAbort
, void());
56 MOCK_METHOD1(OnRedirect
, void(bool));
57 MOCK_METHOD2(OnCaptivePortalResults
,
58 void(CaptivePortalResult
, CaptivePortalResult
));
61 // Inherits from the ChromeRenderViewHostTestHarness to gain access to
62 // CreateTestWebContents. Since the tests need to micromanage order of
63 // WebContentsObserver function calls, does not actually make sure of
64 // the harness in any other way.
65 class CaptivePortalTabHelperTest
: public ChromeRenderViewHostTestHarness
{
67 CaptivePortalTabHelperTest()
68 : mock_reloader_(new testing::StrictMock
<MockCaptivePortalTabReloader
>) {}
69 ~CaptivePortalTabHelperTest() override
{}
71 void SetUp() override
{
72 ChromeRenderViewHostTestHarness::SetUp();
74 // Load kHttpUrl. This ensures that any subsequent navigation to kHttpsUrl2
75 // will be properly registered as cross-process.
76 content::WebContentsTester
* web_contents_tester
=
77 content::WebContentsTester::For(web_contents());
78 web_contents_tester
->NavigateAndCommit(GURL(kHttpUrl
));
79 content::RenderFrameHostTester
* rfh_tester
=
80 content::RenderFrameHostTester::For(main_rfh());
81 rfh_tester
->SimulateNavigationStop();
83 tab_helper_
.reset(new CaptivePortalTabHelper(web_contents()));
84 tab_helper_
->profile_
= nullptr;
85 tab_helper_
->SetTabReloaderForTest(mock_reloader_
);
88 // Simulates a successful load of |url|.
89 void SimulateSuccess(const GURL
& url
) {
90 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
92 content::WebContentsTester
* web_contents_tester
=
93 content::WebContentsTester::For(web_contents());
94 web_contents_tester
->StartNavigation(url
);
96 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
97 content::RenderFrameHost
* rfh
=
98 pending_main_rfh() ? pending_main_rfh() : main_rfh();
99 content::RenderFrameHostTester::For(rfh
)->SimulateNavigationCommit(url
);
102 // Simulates a connection timeout while requesting |url|.
103 void SimulateTimeout(const GURL
& url
) {
104 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
106 content::WebContentsTester
* web_contents_tester
=
107 content::WebContentsTester::For(web_contents());
108 web_contents_tester
->StartNavigation(url
);
109 content::RenderFrameHost
* rfh
=
110 pending_main_rfh() ? pending_main_rfh() : main_rfh();
111 content::RenderFrameHostTester
* rfh_tester
=
112 content::RenderFrameHostTester::For(rfh
);
114 rfh_tester
->SimulateNavigationError(url
, net::ERR_TIMED_OUT
);
116 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
117 rfh_tester
->SimulateNavigationErrorPageCommit();
120 // Simulates an abort while requesting |url|.
121 void SimulateAbort(const GURL
& url
,
122 NavigationType navigation_type
) {
123 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
125 content::WebContentsTester
* web_contents_tester
=
126 content::WebContentsTester::For(web_contents());
127 web_contents_tester
->StartNavigation(url
);
128 DCHECK_IMPLIES(navigation_type
== kSameProcess
, !pending_main_rfh());
130 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
131 content::RenderFrameHost
* rfh
=
132 navigation_type
== kSameProcess
? main_rfh() : pending_main_rfh();
133 content::RenderFrameHostTester
* rfh_tester
=
134 content::RenderFrameHostTester::For(rfh
);
135 rfh_tester
->SimulateNavigationError(url
, net::ERR_ABORTED
);
136 rfh_tester
->SimulateNavigationStop();
138 // Make sure that above call resulted in abort, for tests that continue
140 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
143 // Simulates an abort while loading an error page.
144 void SimulateAbortTimeout(const GURL
& url
,
145 NavigationType navigation_type
) {
146 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
148 content::WebContentsTester
* web_contents_tester
=
149 content::WebContentsTester::For(web_contents());
150 web_contents_tester
->StartNavigation(url
);
151 DCHECK_IMPLIES(navigation_type
== kSameProcess
, !pending_main_rfh());
153 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
154 content::RenderFrameHost
* rfh
=
155 navigation_type
== kSameProcess
? main_rfh() : pending_main_rfh();
156 content::RenderFrameHostTester
* rfh_tester
=
157 content::RenderFrameHostTester::For(rfh
);
158 rfh_tester
->SimulateNavigationError(url
, net::ERR_TIMED_OUT
);
159 rfh_tester
->SimulateNavigationStop();
161 // Make sure that above call resulted in abort, for tests that continue
163 EXPECT_CALL(mock_reloader(), OnAbort()).Times(0);
166 CaptivePortalTabHelper
* tab_helper() { return tab_helper_
.get(); }
168 // Simulates a captive portal redirect by calling the Observe method.
169 void ObservePortalResult(CaptivePortalResult previous_result
,
170 CaptivePortalResult result
) {
171 content::Source
<Profile
> source_profile(NULL
);
173 CaptivePortalService::Results results
;
174 results
.previous_result
= previous_result
;
175 results
.result
= result
;
176 content::Details
<CaptivePortalService::Results
> details_results(&results
);
178 EXPECT_CALL(mock_reloader(), OnCaptivePortalResults(previous_result
,
180 tab_helper()->Observe(chrome::NOTIFICATION_CAPTIVE_PORTAL_CHECK_RESULT
,
181 source_profile
, details_results
);
184 MockCaptivePortalTabReloader
& mock_reloader() { return *mock_reloader_
; }
186 void SetIsLoginTab() { tab_helper()->SetIsLoginTab(); }
189 scoped_ptr
<CaptivePortalTabHelper
> tab_helper_
;
191 // Owned by |tab_helper_|.
192 testing::StrictMock
<MockCaptivePortalTabReloader
>* mock_reloader_
;
194 DISALLOW_COPY_AND_ASSIGN(CaptivePortalTabHelperTest
);
197 TEST_F(CaptivePortalTabHelperTest
, HttpSuccess
) {
198 SimulateSuccess(GURL(kHttpUrl
));
199 content::RenderFrameHostTester::For(main_rfh())->SimulateNavigationStop();
202 TEST_F(CaptivePortalTabHelperTest
, HttpTimeout
) {
203 SimulateTimeout(GURL(kHttpUrl
));
204 content::RenderFrameHostTester::For(main_rfh())->SimulateNavigationStop();
207 TEST_F(CaptivePortalTabHelperTest
, HttpsSuccess
) {
208 SimulateSuccess(GURL(kHttpsUrl
));
209 content::RenderFrameHostTester::For(main_rfh())->SimulateNavigationStop();
210 EXPECT_FALSE(tab_helper()->IsLoginTab());
213 TEST_F(CaptivePortalTabHelperTest
, HttpsTimeout
) {
214 SimulateTimeout(GURL(kHttpsUrl
));
215 // Make sure no state was carried over from the timeout.
216 SimulateSuccess(GURL(kHttpsUrl
));
217 EXPECT_FALSE(tab_helper()->IsLoginTab());
220 TEST_F(CaptivePortalTabHelperTest
, HttpsAbort
) {
221 SimulateAbort(GURL(kHttpsUrl
), kCrossProcess
);
222 // Make sure no state was carried over from the abort.
223 SimulateSuccess(GURL(kHttpsUrl
));
224 EXPECT_FALSE(tab_helper()->IsLoginTab());
227 // A cross-process navigation is aborted by a same-site navigation.
228 TEST_F(CaptivePortalTabHelperTest
, AbortCrossProcess
) {
229 SimulateAbort(GURL(kHttpsUrl2
), kCrossProcess
);
230 // Make sure no state was carried over from the abort.
231 SimulateSuccess(GURL(kHttpUrl
));
232 EXPECT_FALSE(tab_helper()->IsLoginTab());
235 // Abort while there's a provisional timeout error page loading.
236 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeout
) {
237 SimulateAbortTimeout(GURL(kHttpsUrl
), kCrossProcess
);
238 // Make sure no state was carried over from the timeout or the abort.
239 SimulateSuccess(GURL(kHttpsUrl
));
240 EXPECT_FALSE(tab_helper()->IsLoginTab());
243 // Abort a cross-process navigation while there's a provisional timeout error
245 TEST_F(CaptivePortalTabHelperTest
, AbortTimeoutCrossProcess
) {
246 SimulateAbortTimeout(GURL(kHttpsUrl2
), kCrossProcess
);
247 // Make sure no state was carried over from the timeout or the abort.
248 SimulateSuccess(GURL(kHttpsUrl
));
249 EXPECT_FALSE(tab_helper()->IsLoginTab());
252 // Opposite case from above - a same-process error page is aborted in favor of
253 // a cross-process one.
254 TEST_F(CaptivePortalTabHelperTest
, HttpsAbortTimeoutForCrossProcess
) {
255 SimulateSuccess(GURL(kHttpsUrl
));
256 content::RenderFrameHostTester::For(main_rfh())->SimulateNavigationStop();
258 SimulateAbortTimeout(GURL(kHttpsUrl
), kSameProcess
);
259 // Make sure no state was carried over from the timeout or the abort.
260 SimulateSuccess(GURL(kHttpsUrl2
));
261 EXPECT_FALSE(tab_helper()->IsLoginTab());
264 // A provisional same-site navigation is interrupted by a cross-process
265 // navigation without sending an abort first.
266 TEST_F(CaptivePortalTabHelperTest
, UnexpectedProvisionalLoad
) {
267 GURL same_site_url
= GURL(kHttpUrl
);
268 GURL cross_process_url
= GURL(kHttpsUrl2
);
270 // A same-site load for the original RenderViewHost starts.
271 EXPECT_CALL(mock_reloader(),
272 OnLoadStart(same_site_url
.SchemeIsCryptographic())).Times(1);
273 content::RenderFrameHostTester
* rfh_tester
=
274 content::RenderFrameHostTester::For(main_rfh());
275 rfh_tester
->SimulateNavigationStart(same_site_url
);
277 // It's unexpectedly interrupted by a cross-process navigation, which starts
278 // navigating before the old navigation cancels.
279 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
280 EXPECT_CALL(mock_reloader(),
281 OnLoadStart(cross_process_url
.SchemeIsCryptographic())).Times(1);
282 content::WebContentsTester::For(web_contents())
283 ->StartNavigation(cross_process_url
);
285 // The cross-process navigation fails.
286 content::RenderFrameHostTester
* pending_rfh_tester
=
287 content::RenderFrameHostTester::For(pending_main_rfh());
288 pending_rfh_tester
->SimulateNavigationError(cross_process_url
,
291 // The same-site navigation finally is aborted.
292 rfh_tester
->SimulateNavigationStop();
294 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_FAILED
)).Times(1);
295 pending_rfh_tester
->SimulateNavigationErrorPageCommit();
298 // Similar to the above test, except the original RenderViewHost manages to
299 // commit before its navigation is aborted.
300 TEST_F(CaptivePortalTabHelperTest
, UnexpectedCommit
) {
301 GURL same_site_url
= GURL(kHttpUrl
);
302 GURL cross_process_url
= GURL(kHttpsUrl2
);
304 // A same-site load for the original RenderViewHost starts.
305 EXPECT_CALL(mock_reloader(),
306 OnLoadStart(same_site_url
.SchemeIsCryptographic())).Times(1);
307 content::RenderFrameHostTester
* rfh_tester
=
308 content::RenderFrameHostTester::For(main_rfh());
309 rfh_tester
->SimulateNavigationStart(same_site_url
);
311 // It's unexpectedly interrupted by a cross-process navigation, which starts
312 // navigating before the old navigation cancels.
313 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
314 EXPECT_CALL(mock_reloader(),
315 OnLoadStart(cross_process_url
.SchemeIsCryptographic())).Times(1);
316 content::WebContentsTester::For(web_contents())
317 ->StartNavigation(cross_process_url
);
319 // The cross-process navigation fails.
320 content::RenderFrameHostTester::For(pending_main_rfh())
321 ->SimulateNavigationError(cross_process_url
, net::ERR_FAILED
);
323 // The same-site navigation succeeds.
324 EXPECT_CALL(mock_reloader(), OnAbort()).Times(1);
325 EXPECT_CALL(mock_reloader(),
326 OnLoadStart(same_site_url
.SchemeIsCryptographic()))
328 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
329 rfh_tester
->SimulateNavigationCommit(same_site_url
);
332 // Simulates navigations for a number of subframes, and makes sure no
333 // CaptivePortalTabHelper function is called.
334 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframe
) {
335 GURL url
= GURL(kHttpsUrl
);
337 content::RenderFrameHostTester
* rfh_tester
=
338 content::RenderFrameHostTester::For(main_rfh());
339 content::RenderFrameHost
* subframe1
= rfh_tester
->AppendChild("subframe1");
342 content::RenderFrameHostTester
* subframe_tester1
=
343 content::RenderFrameHostTester::For(subframe1
);
344 subframe_tester1
->SimulateNavigationStart(url
);
345 subframe_tester1
->SimulateNavigationCommit(url
);
346 subframe_tester1
->SimulateNavigationStop();
349 content::RenderFrameHost
* subframe2
= rfh_tester
->AppendChild("subframe2");
350 content::RenderFrameHostTester
* subframe_tester2
=
351 content::RenderFrameHostTester::For(subframe2
);
352 subframe_tester2
->SimulateNavigationStart(url
);
353 subframe_tester2
->SimulateNavigationError(url
, net::ERR_TIMED_OUT
);
354 subframe_tester2
->SimulateNavigationStop();
357 content::RenderFrameHost
* subframe3
= rfh_tester
->AppendChild("subframe3");
358 content::RenderFrameHostTester
* subframe_tester3
=
359 content::RenderFrameHostTester::For(subframe3
);
360 subframe_tester3
->SimulateNavigationStart(url
);
361 subframe_tester3
->SimulateNavigationError(url
, net::ERR_ABORTED
);
362 subframe_tester3
->SimulateNavigationStop();
365 // Simulates a subframe erroring out at the same time as a provisional load,
366 // but with a different error code. Make sure the TabHelper sees the correct
368 TEST_F(CaptivePortalTabHelperTest
, HttpsSubframeParallelError
) {
369 // URL used by both frames.
370 GURL url
= GURL(kHttpsUrl
);
371 content::RenderFrameHostTester
* rfh_tester
=
372 content::RenderFrameHostTester::For(main_rfh());
373 content::RenderFrameHost
* subframe
= rfh_tester
->AppendChild("subframe");
374 content::RenderFrameHostTester
* subframe_tester
=
375 content::RenderFrameHostTester::For(subframe
);
378 EXPECT_CALL(mock_reloader(), OnLoadStart(url
.SchemeIsCryptographic()))
380 rfh_tester
->SimulateNavigationStart(url
);
381 subframe_tester
->SimulateNavigationStart(url
);
383 // Loads return errors.
384 rfh_tester
->SimulateNavigationError(url
, net::ERR_UNEXPECTED
);
385 subframe_tester
->SimulateNavigationError(url
, net::ERR_TIMED_OUT
);
387 // Error page load finishes.
388 subframe_tester
->SimulateNavigationErrorPageCommit();
389 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_UNEXPECTED
)).Times(1);
390 rfh_tester
->SimulateNavigationErrorPageCommit();
393 // Simulates an HTTP to HTTPS redirect, which then times out.
394 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpsRedirectTimeout
) {
395 GURL
http_url(kHttpUrl
);
396 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
397 content::RenderFrameHostTester
* rfh_tester
=
398 content::RenderFrameHostTester::For(main_rfh());
399 rfh_tester
->SimulateNavigationStart(http_url
);
401 GURL
https_url(kHttpsUrl
);
402 EXPECT_CALL(mock_reloader(), OnRedirect(true)).Times(1);
403 rfh_tester
->SimulateRedirect(https_url
);
405 rfh_tester
->SimulateNavigationError(https_url
, net::ERR_TIMED_OUT
);
407 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::ERR_TIMED_OUT
)).Times(1);
408 rfh_tester
->SimulateNavigationErrorPageCommit();
411 // Simulates an HTTPS to HTTP redirect.
412 TEST_F(CaptivePortalTabHelperTest
, HttpsToHttpRedirect
) {
413 GURL
https_url(kHttpsUrl
);
414 EXPECT_CALL(mock_reloader(), OnLoadStart(https_url
.SchemeIsCryptographic()))
416 content::RenderFrameHostTester
* rfh_tester
=
417 content::RenderFrameHostTester::For(main_rfh());
418 rfh_tester
->SimulateNavigationStart(https_url
);
420 GURL
http_url(kHttpUrl
);
421 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsCryptographic()))
423 rfh_tester
->SimulateRedirect(http_url
);
425 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
426 rfh_tester
->SimulateNavigationCommit(http_url
);
429 // Simulates an HTTP to HTTP redirect.
430 TEST_F(CaptivePortalTabHelperTest
, HttpToHttpRedirect
) {
431 GURL
http_url(kHttpUrl
);
432 EXPECT_CALL(mock_reloader(), OnLoadStart(http_url
.SchemeIsCryptographic()))
434 content::RenderFrameHostTester
* rfh_tester
=
435 content::RenderFrameHostTester::For(main_rfh());
436 rfh_tester
->SimulateNavigationStart(http_url
);
438 EXPECT_CALL(mock_reloader(), OnRedirect(http_url
.SchemeIsCryptographic()))
440 rfh_tester
->SimulateRedirect(http_url
);
442 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
443 rfh_tester
->SimulateNavigationCommit(http_url
);
446 // Tests that a subframe redirect doesn't reset the timer to kick off a captive
447 // portal probe for the main frame if the main frame request is taking too long.
448 TEST_F(CaptivePortalTabHelperTest
, SubframeRedirect
) {
449 GURL
http_url(kHttpUrl
);
450 content::RenderFrameHostTester
* rfh_tester
=
451 content::RenderFrameHostTester::For(main_rfh());
452 content::RenderFrameHost
* subframe
= rfh_tester
->AppendChild("subframe");
453 content::RenderFrameHostTester
* subframe_tester
=
454 content::RenderFrameHostTester::For(subframe
);
456 EXPECT_CALL(mock_reloader(), OnLoadStart(false)).Times(1);
457 rfh_tester
->SimulateNavigationStart(http_url
);
458 subframe_tester
->SimulateNavigationStart(http_url
);
460 GURL
https_url(kHttpsUrl
);
461 subframe_tester
->SimulateRedirect(https_url
);
463 EXPECT_CALL(mock_reloader(), OnLoadCommitted(net::OK
)).Times(1);
464 rfh_tester
->SimulateNavigationCommit(http_url
);
467 TEST_F(CaptivePortalTabHelperTest
, LoginTabLogin
) {
468 EXPECT_FALSE(tab_helper()->IsLoginTab());
470 EXPECT_TRUE(tab_helper()->IsLoginTab());
472 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
473 captive_portal::RESULT_INTERNET_CONNECTED
);
474 EXPECT_FALSE(tab_helper()->IsLoginTab());
477 TEST_F(CaptivePortalTabHelperTest
, LoginTabError
) {
478 EXPECT_FALSE(tab_helper()->IsLoginTab());
481 EXPECT_TRUE(tab_helper()->IsLoginTab());
483 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
484 captive_portal::RESULT_NO_RESPONSE
);
485 EXPECT_FALSE(tab_helper()->IsLoginTab());
488 TEST_F(CaptivePortalTabHelperTest
, LoginTabMultipleResultsBeforeLogin
) {
489 EXPECT_FALSE(tab_helper()->IsLoginTab());
492 EXPECT_TRUE(tab_helper()->IsLoginTab());
494 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
495 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
496 EXPECT_TRUE(tab_helper()->IsLoginTab());
498 ObservePortalResult(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
499 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
500 EXPECT_TRUE(tab_helper()->IsLoginTab());
502 ObservePortalResult(captive_portal::RESULT_NO_RESPONSE
,
503 captive_portal::RESULT_INTERNET_CONNECTED
);
504 EXPECT_FALSE(tab_helper()->IsLoginTab());
507 TEST_F(CaptivePortalTabHelperTest
, NoLoginTab
) {
508 EXPECT_FALSE(tab_helper()->IsLoginTab());
510 ObservePortalResult(captive_portal::RESULT_INTERNET_CONNECTED
,
511 captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
);
512 EXPECT_FALSE(tab_helper()->IsLoginTab());
514 ObservePortalResult(captive_portal::RESULT_BEHIND_CAPTIVE_PORTAL
,
515 captive_portal::RESULT_NO_RESPONSE
);
516 EXPECT_FALSE(tab_helper()->IsLoginTab());
518 ObservePortalResult(captive_portal::RESULT_NO_RESPONSE
,
519 captive_portal::RESULT_INTERNET_CONNECTED
);
520 EXPECT_FALSE(tab_helper()->IsLoginTab());