1 // Copyright 2018 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 package org.chromium.chrome.browser.login; 6 7 import android.support.test.InstrumentationRegistry; 8 9 import androidx.test.filters.MediumTest; 10 11 import org.hamcrest.Matchers; 12 import org.junit.After; 13 import org.junit.Before; 14 import org.junit.Rule; 15 import org.junit.Test; 16 import org.junit.runner.RunWith; 17 18 import org.chromium.base.Callback; 19 import org.chromium.base.test.util.CallbackHelper; 20 import org.chromium.base.test.util.CommandLineFlags; 21 import org.chromium.base.test.util.Criteria; 22 import org.chromium.base.test.util.CriteriaHelper; 23 import org.chromium.base.test.util.Restriction; 24 import org.chromium.chrome.browser.customtabs.CustomTabActivityTestRule; 25 import org.chromium.chrome.browser.flags.ChromeSwitches; 26 import org.chromium.chrome.browser.tab.SadTab; 27 import org.chromium.chrome.browser.tab.Tab; 28 import org.chromium.chrome.browser.tab.TabLaunchType; 29 import org.chromium.chrome.test.ChromeJUnit4ClassRunner; 30 import org.chromium.chrome.test.ChromeTabbedActivityTestRule; 31 import org.chromium.chrome.test.util.ChromeTabUtils; 32 import org.chromium.content_public.browser.test.util.TestThreadUtils; 33 import org.chromium.content_public.common.ContentUrlConstants; 34 import org.chromium.net.test.EmbeddedTestServer; 35 36 import java.util.concurrent.atomic.AtomicReference; 37 38 /** 39 * Tests for the Android specific HTTP auth UI. 40 */ 41 @RunWith(ChromeJUnit4ClassRunner.class) 42 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) 43 public class ChromeHttpAuthHandlerTest { 44 @Rule 45 public ChromeTabbedActivityTestRule mActivityTestRule = new ChromeTabbedActivityTestRule(); 46 47 @Rule 48 public CustomTabActivityTestRule mCustomTabActivityTestRule = new CustomTabActivityTestRule(); 49 50 private EmbeddedTestServer mTestServer; 51 52 @Before setUp()53 public void setUp() throws Exception { 54 mActivityTestRule.startMainActivityOnBlankPage(); 55 mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationRegistry.getContext()); 56 } 57 58 @After tearDown()59 public void tearDown() { 60 if (mTestServer != null) mTestServer.stopAndDestroyServer(); 61 } 62 63 @Test 64 @MediumTest authDialogShows()65 public void authDialogShows() throws Exception { 66 ChromeHttpAuthHandler handler = triggerAuth(); 67 verifyAuthDialogVisibility(handler, true); 68 } 69 70 @Test 71 @MediumTest authDialogDismissOnNavigation()72 public void authDialogDismissOnNavigation() throws Exception { 73 ChromeHttpAuthHandler handler = triggerAuth(); 74 verifyAuthDialogVisibility(handler, true); 75 ChromeTabUtils.loadUrlOnUiThread(mActivityTestRule.getActivity().getActivityTab(), 76 ContentUrlConstants.ABOUT_BLANK_DISPLAY_URL); 77 verifyAuthDialogVisibility(handler, false); 78 } 79 80 @Test 81 @MediumTest authDialogDismissOnTabSwitched()82 public void authDialogDismissOnTabSwitched() throws Exception { 83 ChromeHttpAuthHandler handler = triggerAuth(); 84 verifyAuthDialogVisibility(handler, true); 85 TestThreadUtils.runOnUiThreadBlocking( 86 () 87 -> mActivityTestRule.getActivity().getTabCreator(false).launchUrl( 88 "about:blank", TabLaunchType.FROM_CHROME_UI)); 89 verifyAuthDialogVisibility(handler, false); 90 } 91 92 @Test 93 @MediumTest authDialogDismissOnTabClosed()94 public void authDialogDismissOnTabClosed() throws Exception { 95 ChromeHttpAuthHandler handler = triggerAuth(); 96 verifyAuthDialogVisibility(handler, true); 97 ChromeTabUtils.closeCurrentTab( 98 InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity()); 99 verifyAuthDialogVisibility(handler, false); 100 } 101 102 @Test 103 @MediumTest 104 @Restriction(Restriction.RESTRICTION_TYPE_NON_LOW_END_DEVICE) authDialogSuppressedOnBackgroundTab()105 public void authDialogSuppressedOnBackgroundTab() throws Exception { 106 Tab firstTab = mActivityTestRule.getActivity().getActivityTab(); 107 ChromeTabUtils.newTabFromMenu( 108 InstrumentationRegistry.getInstrumentation(), mActivityTestRule.getActivity()); 109 // If the first tab was closed due to OOM, then just exit the test. 110 if (TestThreadUtils.runOnUiThreadBlocking( 111 () -> firstTab.isClosing() || SadTab.isShowing(firstTab))) { 112 return; 113 } 114 ChromeHttpAuthHandler handler = triggerAuthForTab(firstTab); 115 verifyAuthDialogVisibility(handler, false); 116 } 117 triggerAuth()118 private ChromeHttpAuthHandler triggerAuth() throws Exception { 119 return triggerAuthForTab(mActivityTestRule.getActivity().getActivityTab()); 120 } 121 triggerAuthForTab(Tab tab)122 private ChromeHttpAuthHandler triggerAuthForTab(Tab tab) throws Exception { 123 AtomicReference<ChromeHttpAuthHandler> handlerRef = new AtomicReference<>(); 124 CallbackHelper handlerCallback = new CallbackHelper(); 125 Callback<ChromeHttpAuthHandler> callback = (handler) -> { 126 handlerRef.set(handler); 127 handlerCallback.notifyCalled(); 128 }; 129 TestThreadUtils.runOnUiThreadBlocking( 130 () -> { ChromeHttpAuthHandler.setTestCreationCallback(callback); }); 131 132 String url = mTestServer.getURL("/auth-basic"); 133 ChromeTabUtils.loadUrlOnUiThread(tab, url); 134 handlerCallback.waitForFirst(); 135 TestThreadUtils.runOnUiThreadBlocking( 136 () -> { ChromeHttpAuthHandler.setTestCreationCallback(null); }); 137 return handlerRef.get(); 138 } 139 verifyAuthDialogVisibility(ChromeHttpAuthHandler handler, boolean isVisible)140 private void verifyAuthDialogVisibility(ChromeHttpAuthHandler handler, boolean isVisible) { 141 CriteriaHelper.pollUiThread( 142 () -> Criteria.checkThat(handler.isShowingAuthDialog(), Matchers.is(isVisible))); 143 } 144 } 145