OLD | NEW |
---|---|
(Empty) | |
1 // Copyright 2014 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 android.test.suitebuilder.annotation.MediumTest; | |
8 import android.view.View; | |
9 import android.view.ViewGroup; | |
10 | |
11 import org.chromium.base.ThreadUtils; | |
12 import org.chromium.base.test.util.Feature; | |
13 import org.chromium.base.test.util.UrlUtils; | |
14 import org.chromium.chrome.R; | |
15 import org.chromium.chrome.browser.autofill.PersonalDataManager.AutofillProfile; | |
16 import org.chromium.chrome.shell.ChromeShellActivity; | |
17 import org.chromium.chrome.shell.ChromeShellTestBase; | |
18 import org.chromium.content.browser.ContentViewCore; | |
19 import org.chromium.content.browser.test.util.Criteria; | |
20 import org.chromium.content.browser.test.util.CriteriaHelper; | |
21 import org.chromium.content.browser.test.util.DOMUtils; | |
22 import org.chromium.content_public.browser.WebContents; | |
23 import org.chromium.ui.UiUtils; | |
24 import org.chromium.ui.autofill.AutofillPopup; | |
25 | |
26 import java.util.concurrent.Callable; | |
27 import java.util.concurrent.ExecutionException; | |
28 import java.util.concurrent.TimeoutException; | |
29 | |
30 /** | |
31 * Integration tests for interaction of the AutofillPopup and a keyboard. | |
32 */ | |
33 public class AutofillPopupWithKeyboardTest extends ChromeShellTestBase { | |
34 /** | |
35 * Test that showing autofill popup and keyboard will not hide the autofill popup. | |
36 */ | |
37 @MediumTest | |
38 @Feature({"autofill-keyboard"}) | |
39 public void testShowAutofillPopupAndKeyboardimultaneously() | |
40 throws InterruptedException, ExecutionException, TimeoutException { | |
41 launchChromeShellWithUrl(UrlUtils.encodeHtmlDataUri("<html><head>" | |
42 + "<meta name=\"viewport\"" | |
43 + "content=\"width=device-width, initial-scale=1.0, maximum-scal e=1.0\" /></head>" | |
44 + "<body><form method=\"POST\">" | |
45 + "<input type=\"text\" id=\"fn\" autocomplete=\"given-name\" /> <br>" | |
46 + "<input type=\"text\" id=\"ln\" autocomplete=\"family-name\" / ><br>" | |
47 + "<textarea id=\"sa\" autocomplete=\"street-address\"></textare a><br>" | |
48 + "<input type=\"text\" id=\"a1\" autocomplete=\"address-line1\" /><br>" | |
49 + "<input type=\"text\" id=\"a2\" autocomplete=\"address-line2\" /><br>" | |
50 + "<input type=\"text\" id=\"ct\" autocomplete=\"locality\" /><b r>" | |
51 + "<input type=\"text\" id=\"zc\" autocomplete=\"postal-code\" / ><br>" | |
52 + "<input type=\"text\" id=\"em\" autocomplete=\"email\" /><br>" | |
53 + "<input type=\"text\" id=\"ph\" autocomplete=\"tel\" /><br>" | |
54 + "<input type=\"text\" id=\"fx\" autocomplete=\"fax\" /><br>" | |
55 + "<select id=\"co\" autocomplete=\"country\"><br>" | |
56 + "<option value=\"BR\">Brazil</option>" | |
57 + "<option value=\"US\">United States</option>" | |
58 + "</select>" | |
59 + "<input type=\"submit\" />" | |
60 + "</form></body></html>")); | |
61 assertTrue(waitForActiveShellToBeDoneLoading()); | |
62 new AutofillTestHelper().setProfile(new AutofillProfile("", "https://www .example.com", | |
63 "John Smith", "Acme Inc", "1 Main\nApt A", "CA", "San Francisco" , "", "94102", "", | |
64 "US", "(415) 888-9999", "john@acme.inc", "en")); | |
65 class Info { | |
newt (away)
2015/01/20 21:28:09
Another option would be to use AtomicReferences in
please use gerrit instead
2015/01/21 01:31:44
Done, that saves 2 lines :-).
| |
66 public final ContentViewCore viewCore; | |
67 public final WebContents webContents; | |
68 public final ViewGroup view; | |
69 public Info(ChromeShellActivity activity) { | |
70 viewCore = activity.getActiveContentViewCore(); | |
71 webContents = viewCore.getWebContents(); | |
72 view = viewCore.getContainerView(); | |
73 } | |
74 } | |
75 final Info info = ThreadUtils.runOnUiThreadBlocking(new Callable<Info>() { | |
76 @Override | |
77 public Info call() { | |
78 return new Info(getActivity()); | |
79 } | |
80 }); | |
81 assertTrue(DOMUtils.waitForNonZeroNodeBounds(info.webContents, "fn")); | |
82 | |
83 // Click on the unfocused input element the first time to focus on it. T his brings up the | |
84 // keyboard, but does not show the autofill popup. | |
85 DOMUtils.clickNode(this, info.viewCore, "fn"); | |
86 waitForKeyboardShownOnUiThreadBlocking(); | |
87 notifyViewHeightReducedOnUiThreadBlocking(); | |
88 | |
89 // Hide the keyboard while still keeping the focus on the input field. | |
90 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
91 @Override | |
92 public void run() { | |
93 UiUtils.hideKeyboard(info.view); | |
94 } | |
95 }); | |
96 assertTrue("Keyboard was never hidden", CriteriaHelper.pollForCriteria(n ew Criteria() { | |
97 @Override | |
98 public boolean isSatisfied() { | |
99 try { | |
100 return !isKeyboardShowingOnUiThreadBlocking(); | |
101 } catch (InterruptedException e1) { | |
102 return false; | |
103 } catch (ExecutionException e2) { | |
104 return false; | |
105 } | |
106 } | |
107 })); | |
108 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
109 @Override | |
110 public void run() { | |
111 info.viewCore.onSizeChanged(info.viewCore.getViewportWidthPix(), | |
112 info.viewCore.getViewportHeightPix() + 100, | |
113 info.viewCore.getViewportWidthPix(), info.viewCore.getVi ewportHeightPix()); | |
114 } | |
115 }); | |
116 | |
117 // Click on the focused input element the second time. This brings up th e autofill popup and | |
118 // shows the keyboard at the same time. Showing the keyboard should not hide the autofill | |
119 // popup. | |
120 DOMUtils.clickNode(this, info.viewCore, "fn"); | |
121 waitForKeyboardShownOnUiThreadBlocking(); | |
122 notifyViewHeightReducedOnUiThreadBlocking(); | |
123 | |
124 // Verify that the autofill popup is showing. | |
125 assertTrue("Autofill Popup anchor view was never added.", | |
126 CriteriaHelper.pollForCriteria(new Criteria() { | |
127 @Override | |
128 public boolean isSatisfied() { | |
129 try { | |
130 return findAchorViewOnUiThreadBlocking(info.view) != null; | |
131 } catch (InterruptedException e1) { | |
132 return false; | |
133 } catch (ExecutionException e2) { | |
134 return false; | |
135 } | |
136 } | |
137 })); | |
138 final View anchorView = findAchorViewOnUiThreadBlocking(info.view); | |
139 Object popupObject = ThreadUtils.runOnUiThreadBlocking(new Callable<Obje ct>() { | |
140 @Override | |
141 public Object call() { | |
142 return anchorView.getTag(); | |
143 } | |
144 }); | |
145 assertTrue(popupObject instanceof AutofillPopup); | |
146 final AutofillPopup popup = (AutofillPopup) popupObject; | |
147 assertTrue( | |
148 "Autofill Popup was never shown.", CriteriaHelper.pollForCriteri a(new Criteria() { | |
149 @Override | |
150 public boolean isSatisfied() { | |
151 try { | |
152 return isPopupShowingOnUiThreadBlocking(popup); | |
153 } catch (InterruptedException e1) { | |
154 return false; | |
155 } catch (ExecutionException e2) { | |
156 return false; | |
157 } | |
158 } | |
159 })); | |
160 } | |
161 | |
162 // Wait until the keyboard is showing on the UI thread. | |
163 private void waitForKeyboardShownOnUiThreadBlocking() throws InterruptedExce ption { | |
newt (away)
2015/01/20 21:28:10
you could add a "visible" parameter to this method
please use gerrit instead
2015/01/21 01:31:44
Done.
| |
164 assertTrue("Keyboard was never shown", CriteriaHelper.pollForCriteria(ne w Criteria() { | |
newt (away)
2015/01/20 21:28:09
use pollForUIThreadCriteria() here, then you can s
please use gerrit instead
2015/01/21 01:31:44
Done.
| |
165 @Override | |
166 public boolean isSatisfied() { | |
167 try { | |
168 return isKeyboardShowingOnUiThreadBlocking(); | |
169 } catch (InterruptedException e1) { | |
170 return false; | |
171 } catch (ExecutionException e2) { | |
172 return false; | |
173 } | |
174 } | |
175 })); | |
176 } | |
177 | |
178 // Notify the ContentViewCore that its height was reduced on the UI thread. | |
179 private void notifyViewHeightReducedOnUiThreadBlocking() { | |
newt (away)
2015/01/20 21:28:09
I'd remove "OnUiThreadBlocking" from these methods
please use gerrit instead
2015/01/21 01:31:44
Done.
| |
180 ThreadUtils.runOnUiThreadBlocking(new Runnable() { | |
181 @Override | |
182 public void run() { | |
183 ContentViewCore viewCore = getActivity().getActiveContentViewCor e(); | |
184 viewCore.onSizeChanged(viewCore.getViewportWidthPix(), | |
185 viewCore.getViewportHeightPix() - 100, viewCore.getViewp ortWidthPix(), | |
186 viewCore.getViewportHeightPix()); | |
187 } | |
188 }); | |
189 } | |
190 | |
191 // Check whether the keyboard is showing on the UI thread. | |
192 private Boolean isKeyboardShowingOnUiThreadBlocking() | |
newt (away)
2015/01/20 21:28:09
This should return "boolean" (not Boolean). Same b
please use gerrit instead
2015/01/21 01:31:44
No longer relevant, as this method got inlined.
| |
193 throws InterruptedException, ExecutionException { | |
194 return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() { | |
195 @Override | |
196 public Boolean call() { | |
197 return UiUtils.isKeyboardShowing( | |
198 getActivity(), getActivity().getActiveContentViewCore(). getContainerView()); | |
199 } | |
200 }); | |
201 } | |
202 | |
203 // Find the autofill popup view on the UI thread. | |
204 private View findAchorViewOnUiThreadBlocking(final ViewGroup view) | |
205 throws InterruptedException, ExecutionException { | |
206 return ThreadUtils.runOnUiThreadBlocking(new Callable<View>() { | |
newt (away)
2015/01/20 21:28:09
I'd use runOnUiThreadBlockingNoException(). Then y
please use gerrit instead
2015/01/21 01:31:44
No longer necessary, as this got inlined.
| |
207 @Override | |
208 public View call() { | |
209 return view.findViewById(R.id.dropdown_popup_window); | |
210 } | |
211 }); | |
212 } | |
213 | |
214 // Check whether the autofill popup is showing on the UI thread. | |
215 private Boolean isPopupShowingOnUiThreadBlocking(final AutofillPopup popup) | |
216 throws InterruptedException, ExecutionException { | |
217 return ThreadUtils.runOnUiThreadBlocking(new Callable<Boolean>() { | |
218 @Override | |
219 public Boolean call() { | |
220 return popup.isShowing(); | |
221 } | |
222 }); | |
223 } | |
224 } | |
OLD | NEW |