Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(390)

Side by Side Diff: chrome/android/javatests/src/org/chromium/chrome/browser/webapps/WebappModeTest.java

Issue 2898373002: Redirects _blank and window.open() off-origin navigation from PWA to CCT. (Closed)
Patch Set: Merge Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 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 android.app.Activity; 7 import android.app.Activity;
8 import android.content.Context; 8 import android.content.Context;
9 import android.content.Intent; 9 import android.content.Intent;
10 import android.content.SharedPreferences; 10 import android.content.SharedPreferences;
11 import android.support.test.InstrumentationRegistry; 11 import android.support.test.InstrumentationRegistry;
12 import android.support.test.filters.MediumTest; 12 import android.support.test.filters.MediumTest;
13 import android.view.View; 13 import android.view.View;
14 14
15 import org.junit.After; 15 import org.junit.After;
16 import org.junit.Assert; 16 import org.junit.Assert;
17 import org.junit.Before; 17 import org.junit.Before;
18 import org.junit.Rule; 18 import org.junit.Rule;
19 import org.junit.Test; 19 import org.junit.Test;
20 import org.junit.runner.RunWith; 20 import org.junit.runner.RunWith;
21 21
22 import org.chromium.base.ApplicationStatus; 22 import org.chromium.base.ApplicationStatus;
23 import org.chromium.base.ContextUtils; 23 import org.chromium.base.ContextUtils;
24 import org.chromium.base.ThreadUtils;
25 import org.chromium.base.test.util.CommandLineFlags; 24 import org.chromium.base.test.util.CommandLineFlags;
26 import org.chromium.base.test.util.Feature; 25 import org.chromium.base.test.util.Feature;
27 import org.chromium.base.test.util.RetryOnFailure; 26 import org.chromium.base.test.util.RetryOnFailure;
28 import org.chromium.base.test.util.UrlUtils; 27 import org.chromium.base.test.util.UrlUtils;
29 import org.chromium.blink_public.platform.WebDisplayMode; 28 import org.chromium.blink_public.platform.WebDisplayMode;
30 import org.chromium.chrome.browser.ChromeActivity; 29 import org.chromium.chrome.browser.ChromeActivity;
31 import org.chromium.chrome.browser.ChromeSwitches; 30 import org.chromium.chrome.browser.ChromeSwitches;
32 import org.chromium.chrome.browser.ChromeTabbedActivity; 31 import org.chromium.chrome.browser.ChromeTabbedActivity;
33 import org.chromium.chrome.browser.ShortcutHelper; 32 import org.chromium.chrome.browser.ShortcutHelper;
34 import org.chromium.chrome.browser.ShortcutSource; 33 import org.chromium.chrome.browser.ShortcutSource;
35 import org.chromium.chrome.browser.tab.Tab; 34 import org.chromium.chrome.browser.tab.Tab;
36 import org.chromium.chrome.browser.tab.TabIdManager; 35 import org.chromium.chrome.browser.tab.TabIdManager;
37 import org.chromium.chrome.test.ChromeJUnit4ClassRunner; 36 import org.chromium.chrome.test.ChromeJUnit4ClassRunner;
38 import org.chromium.chrome.test.MultiActivityTestRule; 37 import org.chromium.chrome.test.MultiActivityTestRule;
39 import org.chromium.chrome.test.util.ActivityUtils;
40 import org.chromium.chrome.test.util.ApplicationTestUtils; 38 import org.chromium.chrome.test.util.ApplicationTestUtils;
41 import org.chromium.chrome.test.util.browser.TabLoadObserver;
42 import org.chromium.content.browser.test.util.Criteria; 39 import org.chromium.content.browser.test.util.Criteria;
43 import org.chromium.content.browser.test.util.CriteriaHelper; 40 import org.chromium.content.browser.test.util.CriteriaHelper;
44 import org.chromium.content.browser.test.util.JavaScriptUtils;
45 import org.chromium.content.browser.test.util.TouchCommon;
46 import org.chromium.content_public.common.ScreenOrientationValues; 41 import org.chromium.content_public.common.ScreenOrientationValues;
47 import org.chromium.net.test.EmbeddedTestServer; 42 import org.chromium.net.test.EmbeddedTestServer;
48 43
49 /** 44 /**
50 * Tests that WebappActivities are launched correctly. 45 * Tests that WebappActivities are launched correctly.
51 * 46 *
52 * This test seems a little wonky because WebappActivities launched differently, depending on what 47 * This test seems a little wonky because WebappActivities launched differently, depending on what
53 * OS the user is on. Pre-L, WebappActivities were manually instanced and assig ned by the 48 * OS the user is on. Pre-L, WebappActivities were manually instanced and assig ned by the
54 * WebappManager. On L and above, WebappActivities are automatically instanced by Android and the 49 * WebappManager. On L and above, WebappActivities are automatically instanced by Android and the
55 * FLAG_ACTIVITY_NEW_DOCUMENT mechanism. Moreover, we don't have access to the task list pre-L so 50 * FLAG_ACTIVITY_NEW_DOCUMENT mechanism. Moreover, we don't have access to the task list pre-L so
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
266 fireWebappIntent(WEBAPP_2_ID, WEBAPP_2_URL, WEBAPP_2_TITLE, WEBAPP_ICON, true); 261 fireWebappIntent(WEBAPP_2_ID, WEBAPP_2_URL, WEBAPP_2_TITLE, WEBAPP_ICON, true);
267 CriteriaHelper.pollUiThread(new Criteria() { 262 CriteriaHelper.pollUiThread(new Criteria() {
268 @Override 263 @Override
269 public boolean isSatisfied() { 264 public boolean isSatisfied() {
270 return isWebappActivityReady(ApplicationStatus.getLastTrackedFoc usedActivity()); 265 return isWebappActivityReady(ApplicationStatus.getLastTrackedFoc usedActivity());
271 } 266 }
272 }); 267 });
273 } 268 }
274 269
275 /** 270 /**
276 * Tests that WebappActivities handle window.open() properly in tabbed mode.
277 */
278 @Test
279 @MediumTest
280 @Feature({"Webapps"})
281 public void testWebappHandlesWindowOpenInTabbedMode() throws Exception {
282 triggerWindowOpenAndWaitForLoad(ChromeTabbedActivity.class, getOnClickLi nkUrl(), true);
283 }
284
285 /**
286 * Tests that WebappActivities handle suppressed window.open() properly in t abbed mode.
287 */
288 @Test
289 @MediumTest
290 @Feature({"Webapps"})
291 public void testWebappHandlesSuppressedWindowOpenInTabbedMode() throws Excep tion {
292 triggerWindowOpenAndWaitForLoad(
293 ChromeTabbedActivity.class, getHrefNoReferrerLinkUrl(), false);
294 }
295
296 private <T extends ChromeActivity> void triggerWindowOpenAndWaitForLoad(
297 Class<T> classToWaitFor, String linkHtml, boolean checkContents) thr ows Exception {
298 final WebappActivity firstActivity =
299 startWebappActivity(WEBAPP_1_ID, WEBAPP_1_URL, WEBAPP_1_TITLE, W EBAPP_ICON);
300 final int firstWebappId = firstActivity.getActivityTab().getId();
301
302 // Load up the test page.
303 new TabLoadObserver(firstActivity.getActivityTab()).fullyLoadUrl(linkHtm l);
304
305 // Do a plain click to make the link open in the main browser via a wind ow.open().
306 // If the window is opened successfully, javascript on the first page tr iggers and changes
307 // its URL as a signal for this test.
308 Runnable fgTrigger = new Runnable() {
309 @Override
310 public void run() {
311 ThreadUtils.runOnUiThreadBlocking(new Runnable() {
312 @Override
313 public void run() {
314 View view = firstActivity.findViewById(android.R.id.cont ent).getRootView();
315 TouchCommon.singleClickView(view);
316 }
317 });
318 }
319 };
320 ChromeActivity secondActivity = ActivityUtils.waitForActivity(
321 InstrumentationRegistry.getInstrumentation(), classToWaitFor, fg Trigger);
322 mTestRule.waitForFullLoad(secondActivity, "The Google");
323 if (checkContents) {
324 Assert.assertEquals("New WebContents was not created", "SUCCESS",
325 firstActivity.getActivityTab().getTitle());
326 }
327 Assert.assertNotSame("Wrong Activity in foreground", firstActivity,
328 ApplicationStatus.getLastTrackedFocusedActivity());
329
330 // Close the child window to kick the user back to the WebappActivity.
331 JavaScriptUtils.executeJavaScript(
332 secondActivity.getActivityTab().getWebContents(), "window.close( )");
333 CriteriaHelper.pollUiThread(new Criteria() {
334 @Override
335 public boolean isSatisfied() {
336 Activity lastActivity = ApplicationStatus.getLastTrackedFocusedA ctivity();
337 if (!isWebappActivityReady(lastActivity)) return false;
338
339 WebappActivity webappActivity = (WebappActivity) lastActivity;
340 return webappActivity.getActivityTab().getId() == firstWebappId;
341 }
342 });
343 ApplicationTestUtils.waitUntilChromeInForeground();
344 }
345
346 /**
347 * Starts a WebappActivity for the given data and waits for it to be initial ized. We can't use 271 * Starts a WebappActivity for the given data and waits for it to be initial ized. We can't use
348 * ActivityUtils.waitForActivity() because of the way WebappActivity is inst anced on pre-L 272 * ActivityUtils.waitForActivity() because of the way WebappActivity is inst anced on pre-L
349 * devices. 273 * devices.
350 */ 274 */
351 private WebappActivity startWebappActivity(String id, String url, String tit le, String icon) { 275 private WebappActivity startWebappActivity(String id, String url, String tit le, String icon) {
352 fireWebappIntent(id, url, title, icon, true); 276 fireWebappIntent(id, url, title, icon, true);
353 CriteriaHelper.pollUiThread(new Criteria() { 277 CriteriaHelper.pollUiThread(new Criteria() {
354 @Override 278 @Override
355 public boolean isSatisfied() { 279 public boolean isSatisfied() {
356 Activity lastActivity = ApplicationStatus.getLastTrackedFocusedA ctivity(); 280 Activity lastActivity = ApplicationStatus.getLastTrackedFocusedA ctivity();
357 return isWebappActivityReady(lastActivity); 281 return isWebappActivityReady(lastActivity);
358 } 282 }
359 }); 283 });
360 return (WebappActivity) ApplicationStatus.getLastTrackedFocusedActivity( ); 284 return (WebappActivity) ApplicationStatus.getLastTrackedFocusedActivity( );
361 } 285 }
362 286
363 /** Returns true when the last Activity is a WebappActivity and is ready for testing .*/ 287 /** Returns true when the last Activity is a WebappActivity and is ready for testing .*/
364 private boolean isWebappActivityReady(Activity lastActivity) { 288 private boolean isWebappActivityReady(Activity lastActivity) {
365 if (!(lastActivity instanceof WebappActivity)) return false; 289 if (!(lastActivity instanceof WebappActivity)) return false;
366 290
367 WebappActivity webappActivity = (WebappActivity) lastActivity; 291 WebappActivity webappActivity = (WebappActivity) lastActivity;
368 if (webappActivity.getActivityTab() == null) return false; 292 if (webappActivity.getActivityTab() == null) return false;
369 293
370 View rootView = webappActivity.findViewById(android.R.id.content); 294 View rootView = webappActivity.findViewById(android.R.id.content);
371 if (!rootView.hasWindowFocus()) return false; 295 if (!rootView.hasWindowFocus()) return false;
372 296
373 return true; 297 return true;
374 } 298 }
375
376 /** Defines one gigantic link spanning the whole page that creates a new
377 * window with chrome/test/data/android/google.html. Disallowing a referrer from being
378 * sent triggers another codepath.
379 */
380 private String getHrefNoReferrerLinkUrl() {
381 return UrlUtils.encodeHtmlDataUri("<html>"
382 + " <head>"
383 + " <title>href no referrer link page</title>"
384 + " <meta name='viewport'"
385 + " content='width=device-width initial-scale=0.5, maximu m-scale=0.5'>"
386 + " <style>"
387 + " body {margin: 0em;} div {width: 100%; height: 100%; bac kground: #011684;}"
388 + " </style>"
389 + " </head>"
390 + " <body>"
391 + " <a href='" + mTestServer.getURL("/chrome/test/data/androi d/google.html")
392 + "' target='_blank' rel='noreferrer'><div></div></a>"
393 + " </body>");
394 }
395
396 /** Returns a URL where clicking the body triggers a window.open() call to o pen
397 * chrome/test/data/android/google.html. */
398 private String getOnClickLinkUrl() {
399 return UrlUtils.encodeHtmlDataUri("<html>"
400 + " <head>"
401 + " <title>window.open page</title>"
402 + " <meta name='viewport'"
403 + " content='width=device-width initial-scale=0.5, maximu m-scale=0.5'>"
404 + " <style>"
405 + " body {margin: 0em;} div {width: 100%; height: 100%; bac kground: #011684;}"
406 + " </style>"
407 + " <script>"
408 + " function openNewWindow() {"
409 + " var site = window.open('"
410 + mTestServer.getURL("/chrome/test/data/android/google.html") + "');"
411 + " document.title = site ? 'SUCCESS' : 'FAILURE';"
412 + " }"
413 + " </script>"
414 + " </head>"
415 + " <body id='body'>"
416 + " <div onclick='openNewWindow()'></div>"
417 + " </body>"
418 + "</html>");
419 }
420 } 299 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698