OLD | NEW |
1 // Copyright 2017 The Chromium Authors. All rights reserved. | 1 // Copyright 2017 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 package org.chromium.chrome.browser.webapps; | 5 package org.chromium.chrome.browser.webapps; |
6 | 6 |
7 import static org.chromium.base.ApplicationState.HAS_DESTROYED_ACTIVITIES; | |
8 import static org.chromium.base.ApplicationState.HAS_PAUSED_ACTIVITIES; | |
9 import static org.chromium.base.ApplicationState.HAS_STOPPED_ACTIVITIES; | |
10 | |
11 import android.app.Activity; | |
12 import android.content.Intent; | 7 import android.content.Intent; |
13 import android.graphics.Color; | 8 import android.graphics.Color; |
14 import android.support.test.InstrumentationRegistry; | 9 import android.support.test.InstrumentationRegistry; |
15 import android.support.test.filters.SmallTest; | 10 import android.support.test.filters.SmallTest; |
16 | 11 |
17 import org.junit.After; | 12 import org.junit.After; |
18 import org.junit.Assert; | 13 import org.junit.Assert; |
19 import org.junit.Before; | 14 import org.junit.Before; |
20 import org.junit.Rule; | 15 import org.junit.Rule; |
21 import org.junit.Test; | 16 import org.junit.Test; |
22 import org.junit.runner.RunWith; | 17 import org.junit.runner.RunWith; |
23 | 18 |
24 import org.chromium.base.ApiCompatibilityUtils; | 19 import org.chromium.base.ApiCompatibilityUtils; |
25 import org.chromium.base.ApplicationStatus; | |
26 import org.chromium.base.test.util.CommandLineFlags; | 20 import org.chromium.base.test.util.CommandLineFlags; |
27 import org.chromium.base.test.util.Feature; | 21 import org.chromium.base.test.util.Feature; |
28 import org.chromium.chrome.R; | 22 import org.chromium.chrome.R; |
29 import org.chromium.chrome.browser.ChromeSwitches; | 23 import org.chromium.chrome.browser.ChromeSwitches; |
30 import org.chromium.chrome.browser.ChromeTabbedActivity; | 24 import org.chromium.chrome.browser.ChromeTabbedActivity; |
31 import org.chromium.chrome.browser.ShortcutHelper; | 25 import org.chromium.chrome.browser.ShortcutHelper; |
32 import org.chromium.chrome.browser.customtabs.CustomTabActivity; | 26 import org.chromium.chrome.browser.customtabs.CustomTabActivity; |
33 import org.chromium.chrome.browser.externalnav.ExternalNavigationHandler.Overrid
eUrlLoadingResult; | |
34 import org.chromium.chrome.browser.firstrun.FirstRunStatus; | 27 import org.chromium.chrome.browser.firstrun.FirstRunStatus; |
35 import org.chromium.chrome.browser.tab.InterceptNavigationDelegateImpl; | |
36 import org.chromium.chrome.test.ChromeJUnit4ClassRunner; | 28 import org.chromium.chrome.test.ChromeJUnit4ClassRunner; |
37 import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; | 29 import org.chromium.chrome.test.util.browser.contextmenu.ContextMenuUtils; |
38 import org.chromium.content.browser.test.util.Criteria; | |
39 import org.chromium.content.browser.test.util.CriteriaHelper; | |
40 import org.chromium.content.browser.test.util.DOMUtils; | 30 import org.chromium.content.browser.test.util.DOMUtils; |
41 import org.chromium.net.test.EmbeddedTestServer; | 31 import org.chromium.net.test.EmbeddedTestServer; |
42 import org.chromium.ui.base.PageTransition; | 32 import org.chromium.ui.base.PageTransition; |
43 | 33 |
44 /** | 34 /** |
45 * Tests web navigations originating from a WebappActivity. | 35 * Tests web navigations originating from a WebappActivity. |
46 */ | 36 */ |
47 @RunWith(ChromeJUnit4ClassRunner.class) | 37 @RunWith(ChromeJUnit4ClassRunner.class) |
48 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) | 38 @CommandLineFlags.Add({ChromeSwitches.DISABLE_FIRST_RUN_EXPERIENCE}) |
49 public class WebappNavigationTest { | 39 public class WebappNavigationTest { |
50 private static final String YOUTUBE_URL = "https://www.youtube.com/watch?v=E
YmjoW4vIX8"; | |
51 private static final String OFF_ORIGIN_URL = "https://www.google.com/"; | 40 private static final String OFF_ORIGIN_URL = "https://www.google.com/"; |
52 private static final String WEB_APP_PATH = "/chrome/test/data/banners/manife
st_test_page.html"; | 41 private static final String WEB_APP_PATH = "/chrome/test/data/banners/manife
st_test_page.html"; |
53 private static final String IN_SCOPE_PAGE_PATH = | 42 private static final String IN_SCOPE_PAGE_PATH = |
54 "/chrome/test/data/banners/manifest_no_service_worker.html"; | 43 "/chrome/test/data/banners/manifest_no_service_worker.html"; |
55 | 44 |
56 @Rule | 45 @Rule |
57 public final WebappActivityTestRule mActivityTestRule = new WebappActivityTe
stRule(); | 46 public final WebappActivityTestRule mActivityTestRule = new WebappActivityTe
stRule(); |
58 | 47 |
| 48 @Rule |
| 49 public final TopActivityListener activityListener = new TopActivityListener(
); |
| 50 |
59 private EmbeddedTestServer mTestServer; | 51 private EmbeddedTestServer mTestServer; |
60 | 52 |
61 @Before | 53 @Before |
62 public void setUp() throws Exception { | 54 public void setUp() throws Exception { |
63 mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationReg
istry.getContext()); | 55 mTestServer = EmbeddedTestServer.createAndStartServer(InstrumentationReg
istry.getContext()); |
64 } | 56 } |
65 | 57 |
66 @After | 58 @After |
67 public void tearDown() throws Exception { | 59 public void tearDown() throws Exception { |
68 mTestServer.stopAndDestroyServer(); | 60 mTestServer.stopAndDestroyServer(); |
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
121 | 113 |
122 @Test | 114 @Test |
123 @SmallTest | 115 @SmallTest |
124 @Feature({"Webapps"}) | 116 @Feature({"Webapps"}) |
125 public void testInScopeNewTabLinkOpensInCct() throws Exception { | 117 public void testInScopeNewTabLinkOpensInCct() throws Exception { |
126 runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent().putExtr
a( | 118 runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent().putExtr
a( |
127 ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.CYAN)); | 119 ShortcutHelper.EXTRA_THEME_COLOR, (long) Color.CYAN)); |
128 addAnchor("testId", mTestServer.getURL(IN_SCOPE_PAGE_PATH), "_blank"); | 120 addAnchor("testId", mTestServer.getURL(IN_SCOPE_PAGE_PATH), "_blank"); |
129 DOMUtils.clickNode( | 121 DOMUtils.clickNode( |
130 mActivityTestRule.getActivity().getActivityTab().getContentViewC
ore(), "testId"); | 122 mActivityTestRule.getActivity().getActivityTab().getContentViewC
ore(), "testId"); |
131 CustomTabActivity customTab = waitFor(CustomTabActivity.class); | 123 CustomTabActivity customTab = activityListener.waitFor(CustomTabActivity
.class); |
132 mActivityTestRule.waitUntilIdle(customTab); | 124 mActivityTestRule.waitUntilIdle(customTab); |
133 Assert.assertTrue( | 125 Assert.assertTrue( |
134 mActivityTestRule.runJavaScriptCodeInCurrentTab("document.body.t
extContent") | 126 mActivityTestRule.runJavaScriptCodeInCurrentTab("document.body.t
extContent") |
135 .contains("Do-nothing page with a service worker")); | 127 .contains("Do-nothing page with a service worker")); |
136 } | 128 } |
137 | 129 |
138 @Test | 130 @Test |
139 @SmallTest | 131 @SmallTest |
140 @Feature({"Webapps"}) | 132 @Feature({"Webapps"}) |
141 public void testWindowOpenInCct() throws Exception { | 133 public void testWindowOpenInCct() throws Exception { |
(...skipping 28 matching lines...) Expand all Loading... |
170 | 162 |
171 String otherPageUrl = mTestServer.getURL(IN_SCOPE_PAGE_PATH); | 163 String otherPageUrl = mTestServer.getURL(IN_SCOPE_PAGE_PATH); |
172 mActivityTestRule.loadUrlInTab(otherPageUrl, PageTransition.LINK, | 164 mActivityTestRule.loadUrlInTab(otherPageUrl, PageTransition.LINK, |
173 mActivityTestRule.getActivity().getActivityTab()); | 165 mActivityTestRule.getActivity().getActivityTab()); |
174 | 166 |
175 mActivityTestRule.waitUntilIdle(); | 167 mActivityTestRule.waitUntilIdle(); |
176 Assert.assertEquals( | 168 Assert.assertEquals( |
177 otherPageUrl, mActivityTestRule.getActivity().getActivityTab().g
etUrl()); | 169 otherPageUrl, mActivityTestRule.getActivity().getActivityTab().g
etUrl()); |
178 | 170 |
179 Assert.assertSame( | 171 Assert.assertSame( |
180 mActivityTestRule.getActivity(), ApplicationStatus.getLastTracke
dFocusedActivity()); | 172 mActivityTestRule.getActivity(), activityListener.getMostRecentA
ctivity()); |
181 } | 173 } |
182 | 174 |
183 @Test | 175 @Test |
184 @SmallTest | 176 @SmallTest |
185 @Feature({"Webapps"}) | 177 @Feature({"Webapps"}) |
186 public void testOpenInChromeFromContextMenuTabbedChrome() throws Exception { | 178 public void testOpenInChromeFromContextMenuTabbedChrome() throws Exception { |
187 // Needed to get full context menu. | 179 // Needed to get full context menu. |
188 FirstRunStatus.setFirstRunFlowComplete(true); | 180 FirstRunStatus.setFirstRunFlowComplete(true); |
189 runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); | 181 runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); |
190 | 182 |
191 addAnchor("myTestAnchorId", OFF_ORIGIN_URL, "_self"); | 183 addAnchor("myTestAnchorId", OFF_ORIGIN_URL, "_self"); |
192 | 184 |
193 ContextMenuUtils.selectContextMenuItem(InstrumentationRegistry.getInstru
mentation(), | 185 ContextMenuUtils.selectContextMenuItem(InstrumentationRegistry.getInstru
mentation(), |
194 null /* activity to check for focus after click */, | 186 null /* activity to check for focus after click */, |
195 mActivityTestRule.getActivity().getActivityTab(), "myTestAnchorI
d", | 187 mActivityTestRule.getActivity().getActivityTab(), "myTestAnchorI
d", |
196 R.id.menu_id_open_in_chrome); | 188 R.id.menu_id_open_in_chrome); |
197 | 189 |
198 ChromeTabbedActivity tabbedChrome = waitFor(ChromeTabbedActivity.class); | 190 ChromeTabbedActivity tabbedChrome = activityListener.waitFor(ChromeTabbe
dActivity.class); |
199 | 191 |
200 mActivityTestRule.waitUntilIdle(tabbedChrome); | 192 mActivityTestRule.waitUntilIdle(tabbedChrome); |
201 // Dropping the TLD as Google can redirect to a local site, so this coul
d fail outside US. | 193 // Dropping the TLD as Google can redirect to a local site, so this coul
d fail outside US. |
202 Assert.assertTrue(tabbedChrome.getActivityTab().getUrl().startsWith("htt
ps://www.google.")); | 194 Assert.assertTrue(tabbedChrome.getActivityTab().getUrl().startsWith("htt
ps://www.google.")); |
203 } | 195 } |
204 | 196 |
205 @Test | |
206 @SmallTest | |
207 @Feature({"Webapps"}) | |
208 public void testRegularLinkToExternalApp() throws Exception { | |
209 runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); | |
210 | |
211 InterceptNavigationDelegateImpl navigationDelegate = | |
212 mActivityTestRule.getActivity().getActivityTab().getInterceptNav
igationDelegate(); | |
213 | |
214 addAnchor("testLink", YOUTUBE_URL, "_self"); | |
215 DOMUtils.clickNode( | |
216 mActivityTestRule.getActivity().getActivityTab().getContentViewC
ore(), "testLink"); | |
217 | |
218 waitForExternalAppOrIntentPicker(); | |
219 Assert.assertEquals(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTE
NT, | |
220 navigationDelegate.getLastOverrideUrlLoadingResultForTests()); | |
221 } | |
222 | |
223 @Test | |
224 @SmallTest | |
225 @Feature({"Webapps"}) | |
226 public void testNewTabLinkToExternalApp() throws Exception { | |
227 runWebappActivityAndWaitForIdle(mActivityTestRule.createIntent()); | |
228 | |
229 addAnchor("testLink", YOUTUBE_URL, "_blank"); | |
230 DOMUtils.clickNode( | |
231 mActivityTestRule.getActivity().getActivityTab().getContentViewC
ore(), "testLink"); | |
232 | |
233 // For _blank anchors, we open the CustomTab which does the redirecting
if necessary. | |
234 CustomTabActivity customTab = waitFor(CustomTabActivity.class); | |
235 | |
236 waitForExternalAppOrIntentPicker(); | |
237 | |
238 InterceptNavigationDelegateImpl navigationDelegate = | |
239 customTab.getActivityTab().getInterceptNavigationDelegate(); | |
240 Assert.assertEquals(OverrideUrlLoadingResult.OVERRIDE_WITH_EXTERNAL_INTE
NT, | |
241 navigationDelegate.getLastOverrideUrlLoadingResultForTests()); | |
242 } | |
243 | |
244 private void runWebappActivityAndWaitForIdle(Intent intent) throws Exception
{ | 197 private void runWebappActivityAndWaitForIdle(Intent intent) throws Exception
{ |
245 mActivityTestRule.startWebappActivity( | 198 mActivityTestRule.startWebappActivity( |
246 intent.putExtra(ShortcutHelper.EXTRA_URL, mTestServer.getURL(WEB
_APP_PATH))); | 199 intent.putExtra(ShortcutHelper.EXTRA_URL, mTestServer.getURL(WEB
_APP_PATH))); |
247 | 200 |
248 mActivityTestRule.waitUntilSplashscreenHides(); | 201 mActivityTestRule.waitUntilSplashscreenHides(); |
249 mActivityTestRule.waitUntilIdle(); | 202 mActivityTestRule.waitUntilIdle(); |
250 } | 203 } |
251 | 204 |
252 private CustomTabActivity assertCustomTabActivityLaunchedForOffOriginUrl() { | 205 private CustomTabActivity assertCustomTabActivityLaunchedForOffOriginUrl() { |
253 CustomTabActivity customTab = waitFor(CustomTabActivity.class); | 206 CustomTabActivity customTab = activityListener.waitFor(CustomTabActivity
.class); |
254 | 207 |
255 mActivityTestRule.waitUntilIdle(customTab); | 208 mActivityTestRule.waitUntilIdle(customTab); |
256 // Dropping the TLD as Google can redirect to a local site, so this coul
d fail outside US. | 209 // Dropping the TLD as Google can redirect to a local site, so this coul
d fail outside US. |
257 Assert.assertTrue(customTab.getActivityTab().getUrl().contains("https://
www.google.")); | 210 Assert.assertTrue(customTab.getActivityTab().getUrl().contains("https://
www.google.")); |
258 | 211 |
259 return customTab; | 212 return customTab; |
260 } | 213 } |
261 | 214 |
262 private void addAnchor(String id, String url, String target) throws Exceptio
n { | 215 private void addAnchor(String id, String url, String target) throws Exceptio
n { |
263 mActivityTestRule.runJavaScriptCodeInCurrentTab( | 216 mActivityTestRule.runJavaScriptCodeInCurrentTab( |
264 String.format("var aTag = document.createElement('a');" | 217 String.format("var aTag = document.createElement('a');" |
265 + "aTag.id = '%s';" | 218 + "aTag.id = '%s';" |
266 + "aTag.setAttribute('href','%s');" | 219 + "aTag.setAttribute('href','%s');" |
267 + "aTag.setAttribute('target','%s');" | 220 + "aTag.setAttribute('target','%s');" |
268 + "aTag.innerHTML = 'Click Me!';" | 221 + "aTag.innerHTML = 'Click Me!';" |
269 + "document.body.appendChild(aTag);", | 222 + "document.body.appendChild(aTag);", |
270 id, url, target)); | 223 id, url, target)); |
271 } | 224 } |
272 | |
273 @SuppressWarnings("unchecked") | |
274 private <T extends Activity> T waitFor(final Class<T> expectedClass) { | |
275 final Activity[] holder = new Activity[1]; | |
276 CriteriaHelper.pollUiThread(new Criteria() { | |
277 @Override | |
278 public boolean isSatisfied() { | |
279 holder[0] = ApplicationStatus.getLastTrackedFocusedActivity(); | |
280 return holder[0] != null && expectedClass.isAssignableFrom(holde
r[0].getClass()); | |
281 } | |
282 }); | |
283 return (T) holder[0]; | |
284 } | |
285 | |
286 private void waitForExternalAppOrIntentPicker() { | |
287 CriteriaHelper.pollUiThread(new Criteria() { | |
288 @Override | |
289 public boolean isSatisfied() { | |
290 return ApplicationStatus.getStateForApplication() == HAS_PAUSED_
ACTIVITIES | |
291 || ApplicationStatus.getStateForApplication() == HAS_STO
PPED_ACTIVITIES | |
292 || ApplicationStatus.getStateForApplication() == HAS_DES
TROYED_ACTIVITIES; | |
293 } | |
294 }); | |
295 } | |
296 } | 225 } |
OLD | NEW |