1 // Copyright 2013 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.autofill; 6 7 import org.chromium.base.test.util.Feature; 8 import org.chromium.base.test.util.UrlUtils; 9 import org.chromium.chrome.R; 10 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; 11 import org.chromium.chrome.testshell.ChromiumTestShellTestBase; 12 import org.chromium.content.browser.ContentView; 13 import org.chromium.content.browser.test.util.Criteria; 14 import org.chromium.content.browser.test.util.CriteriaHelper; 15 import org.chromium.content.browser.test.util.DOMUtils; 16 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; 17 import org.chromium.content.browser.test.util.TestInputMethodManagerWrapper; 18 import org.chromium.content.browser.test.util.TouchCommon; 19 import org.chromium.ui.autofill.AutofillPopup; 20 21 import android.test.suitebuilder.annotation.MediumTest; 22 import android.text.TextUtils; 23 import android.view.View; 24 25 import java.util.concurrent.ExecutionException; 26 import java.util.concurrent.TimeoutException; 27 28 /** 29 * Integration tests for the AutofillPopup. 30 */ 31 public class AutofillPopupTest extends ChromiumTestShellTestBase { 32 33 private static final String FIRST_NAME = "John"; 34 private static final String LAST_NAME = "Smith"; 35 private static final String COMPANY_NAME = "Acme Inc."; 36 private static final String ADDRESS_LINE1 = "1 Main"; 37 private static final String ADDRESS_LINE2 = "Apt A"; 38 private static final String CITY = "San Francisco"; 39 private static final String STATE = "CA"; 40 private static final String ZIP_CODE = "94102"; 41 private static final String COUNTRY = "US"; 42 private static final String PHONE_NUMBER = "4158889999"; 43 private static final String EMAIL = "john (at) acme.inc"; 44 private static final String ORIGIN = "https://www.example.com"; 45 46 private static final String PAGE_DATA = UrlUtils.encodeHtmlDataUri( 47 "<html><head><meta name=\"viewport\"" + 48 "content=\"width=device-width, initial-scale=1.0, maximum-scale=1.0\" /></head>" + 49 "<body><form method=\"POST\">" + 50 "<input type=\"text\" id=\"fn\" autocomplete=\"given-name\"><br>" + 51 "<input type=\"text\" id=\"ln\" autocomplete=\"family-name\"><br>" + 52 "<input type=\"text\" id=\"a1\" autocomplete=\"address-line1\"><br>" + 53 "<input type=\"text\" id=\"a2\" autocomplete=\"address-line2\"><br>" + 54 "<input type=\"text\" id=\"ct\" autocomplete=\"locality\"><br>" + 55 "<input type=\"text\" id=\"zc\" autocomplete=\"postal-code\"><br>" + 56 "<input type=\"text\" id=\"em\" autocomplete=\"email\"><br>" + 57 "<input type=\"text\" id=\"ph\" autocomplete=\"tel\"><br>" + 58 "<input type=\"submit\" />" + 59 "</form></body></html>"); 60 61 private AutofillTestHelper mHelper; 62 63 @Override 64 public void setUp() throws Exception { 65 super.setUp(); 66 clearAppData(); 67 launchChromiumTestShellWithUrl(PAGE_DATA); 68 assertTrue(waitForActiveShellToBeDoneLoading()); 69 mHelper = new AutofillTestHelper(); 70 } 71 72 @MediumTest 73 @Feature({"autofill"}) 74 public void testClickAutofillPopupSuggestion() 75 throws InterruptedException, ExecutionException, TimeoutException { 76 // The TestInputMethodManagerWrapper intercepts showSoftInput so that a keyboard is never 77 // brought up. 78 final ContentView view = getActivity().getActiveContentView(); 79 final TestInputMethodManagerWrapper immw = 80 new TestInputMethodManagerWrapper(view.getContentViewCore()); 81 view.getContentViewCore().getImeAdapterForTest().setInputMethodManagerWrapper(immw); 82 83 // Add an Autofill profile. 84 AutofillProfile profile = new AutofillProfile( 85 "" /* guid */, ORIGIN, FIRST_NAME + " " + LAST_NAME, COMPANY_NAME, ADDRESS_LINE1, 86 ADDRESS_LINE2, CITY, STATE, ZIP_CODE, COUNTRY, PHONE_NUMBER, EMAIL); 87 String profileOneGUID = mHelper.setProfile(profile); 88 assertEquals(1, mHelper.getNumberOfProfiles()); 89 90 // Click the input field for the first name. 91 final TestCallbackHelperContainer viewClient = new TestCallbackHelperContainer(view); 92 DOMUtils.clickNode(this, view, viewClient, "fn"); 93 94 waitForKeyboardShowRequest(immw, 1); 95 96 view.getContentViewCore().getInputConnectionForTest().setComposingText("J", 1); 97 98 waitForAnchorViewAdd(view); 99 View anchorView = view.findViewById(R.id.autofill_popup_window); 100 101 assertTrue(anchorView.getTag() instanceof AutofillPopup); 102 final AutofillPopup popup = (AutofillPopup) anchorView.getTag(); 103 104 waitForAutofillPopopShow(popup); 105 106 TouchCommon touchCommon = new TouchCommon(this); 107 touchCommon.singleClickViewRelative(popup.getListView(), 10, 10); 108 109 waitForInputFieldFill(view, viewClient); 110 111 assertEquals("First name did not match", 112 FIRST_NAME, DOMUtils.getNodeValue(view, viewClient, "fn")); 113 assertEquals("Last name did not match", 114 LAST_NAME, DOMUtils.getNodeValue(view, viewClient, "ln")); 115 assertEquals("Address line 1 did not match", 116 ADDRESS_LINE1, DOMUtils.getNodeValue(view, viewClient, "a1")); 117 assertEquals("Address line 2 did not match", 118 ADDRESS_LINE2, DOMUtils.getNodeValue(view, viewClient, "a2")); 119 assertEquals("City did not match", 120 CITY, DOMUtils.getNodeValue(view, viewClient, "ct")); 121 assertEquals("Zip code des not match", 122 ZIP_CODE, DOMUtils.getNodeValue(view, viewClient, "zc")); 123 assertEquals("Email does not match", 124 EMAIL, DOMUtils.getNodeValue(view, viewClient, "em")); 125 assertEquals("Phone number does not match", 126 PHONE_NUMBER, DOMUtils.getNodeValue(view, viewClient, "ph")); 127 } 128 129 // Wait and assert helper methods ------------------------------------------------------------- 130 131 private void waitForKeyboardShowRequest(final TestInputMethodManagerWrapper immw, 132 final int count) throws InterruptedException { 133 assertTrue("Keyboard was never requested to be shown.", 134 CriteriaHelper.pollForCriteria(new Criteria() { 135 @Override 136 public boolean isSatisfied() { 137 return immw.getShowSoftInputCounter() == count; 138 } 139 })); 140 } 141 142 private void waitForAnchorViewAdd(final ContentView view) throws InterruptedException { 143 assertTrue("Autofill Popup anchor view was never added.", 144 CriteriaHelper.pollForCriteria(new Criteria() { 145 @Override 146 public boolean isSatisfied() { 147 return view.findViewById(R.id.autofill_popup_window) != null; 148 } 149 })); 150 } 151 152 private void waitForAutofillPopopShow(final AutofillPopup popup) throws InterruptedException { 153 assertTrue("Autofill Popup anchor view was never added.", 154 CriteriaHelper.pollForCriteria(new Criteria() { 155 @Override 156 public boolean isSatisfied() { 157 return popup.isShowing(); 158 } 159 })); 160 } 161 162 private void waitForInputFieldFill(final ContentView view, 163 final TestCallbackHelperContainer viewClient) throws InterruptedException { 164 assertTrue("First name field was never filled.", 165 CriteriaHelper.pollForCriteria(new Criteria() { 166 @Override 167 public boolean isSatisfied() { 168 try { 169 return TextUtils.equals(FIRST_NAME, 170 DOMUtils.getNodeValue(view, viewClient, "fn")); 171 } catch (Exception e) { 172 return false; 173 } 174 } 175 })); 176 } 177 } 178