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

Side by Side Diff: content/shell/android/javatests/src/org/chromium/content_shell_apk/ContentShellTestBase.java

Issue 2632043002: Create ContentShellActivityTestRule and BaseJUnitRunner (Closed)
Patch Set: Change javadoc Created 3 years, 9 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 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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.content_shell_apk; 5 package org.chromium.content_shell_apk;
6 6
7 import static org.chromium.base.test.util.ScalableTimeout.scaleTimeout; 7 import android.app.Instrumentation;
8 import android.content.Intent;
8 9
9 import android.annotation.TargetApi;
10 import android.content.ComponentName;
11 import android.content.Context;
12 import android.content.Intent;
13 import android.net.Uri;
14 import android.os.Build;
15 import android.os.PowerManager;
16 import android.text.TextUtils;
17 import android.view.ViewGroup;
18
19 import org.chromium.base.ThreadUtils;
20 import org.chromium.base.test.BaseActivityInstrumentationTestCase; 10 import org.chromium.base.test.BaseActivityInstrumentationTestCase;
21 import org.chromium.base.test.util.CallbackHelper; 11 import org.chromium.base.test.util.CallbackHelper;
22 import org.chromium.base.test.util.CommandLineFlags; 12 import org.chromium.base.test.util.CommandLineFlags;
23 import org.chromium.base.test.util.UrlUtils;
24 import org.chromium.content.browser.ContentView; 13 import org.chromium.content.browser.ContentView;
25 import org.chromium.content.browser.ContentViewCore; 14 import org.chromium.content.browser.ContentViewCore;
26 import org.chromium.content.browser.test.util.Criteria;
27 import org.chromium.content.browser.test.util.CriteriaHelper;
28 import org.chromium.content.browser.test.util.TestCallbackHelperContainer; 15 import org.chromium.content.browser.test.util.TestCallbackHelperContainer;
29 import org.chromium.content.common.ContentSwitches; 16 import org.chromium.content.common.ContentSwitches;
30 import org.chromium.content_public.browser.LoadUrlParams; 17 import org.chromium.content_public.browser.LoadUrlParams;
31 import org.chromium.content_public.browser.NavigationController; 18 import org.chromium.content_public.browser.NavigationController;
32 import org.chromium.content_public.browser.WebContents; 19 import org.chromium.content_public.browser.WebContents;
33 import org.chromium.content_shell.Shell; 20 import org.chromium.content_shell.Shell;
21 import org.chromium.content_shell_apk.ContentShellActivityTestRule.RerunWithUpda tedContainerView;
22 import org.chromium.content_shell_apk.ContentShellTestCommon.TestCommonCallback;
34 23
35 import java.lang.annotation.ElementType;
36 import java.lang.annotation.Retention;
37 import java.lang.annotation.RetentionPolicy;
38 import java.lang.annotation.Target;
39 import java.lang.reflect.AnnotatedElement; 24 import java.lang.reflect.AnnotatedElement;
40 import java.util.concurrent.Callable;
41 import java.util.concurrent.ExecutionException; 25 import java.util.concurrent.ExecutionException;
42 import java.util.concurrent.TimeUnit;
43 26
44 /** 27 /**
45 * Base test class for all ContentShell based tests. 28 * Base test class for all ContentShell based tests.
46 */ 29 */
47 @CommandLineFlags.Add(ContentSwitches.ENABLE_TEST_INTENTS) 30 @CommandLineFlags.Add(ContentSwitches.ENABLE_TEST_INTENTS)
48 public class ContentShellTestBase 31 public class ContentShellTestBase extends BaseActivityInstrumentationTestCase<Co ntentShellActivity>
49 extends BaseActivityInstrumentationTestCase<ContentShellActivity> { 32 implements TestCommonCallback<ContentShellActivity> {
50 /** The maximum time the waitForActiveShellToBeDoneLoading method will wait. */ 33 protected static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS =
51 private static final long WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT = scaleTimeo ut(10000); 34 ContentShellTestCommon.WAIT_PAGE_LOADING_TIMEOUT_SECONDS;
52 35
53 protected static final long WAIT_PAGE_LOADING_TIMEOUT_SECONDS = scaleTimeout (15); 36 private ContentShellTestCommon mDelegate;
54 37
55 public ContentShellTestBase() { 38 public ContentShellTestBase() {
56 super(ContentShellActivity.class); 39 super(ContentShellActivity.class);
40 mDelegate = new ContentShellTestCommon(this);
41 }
42
43 @SuppressWarnings("deprecation")
44 @Override
45 public ContentShellActivity getActivityForTestCommon() {
46 return getActivity();
57 } 47 }
58 48
59 @Override 49 @Override
50 @SuppressWarnings("deprecation")
51 public Instrumentation getInstrumentationForTestCommon() {
52 return getInstrumentation();
53 }
54
55 @SuppressWarnings("deprecation")
56 @Override
57 public ContentShellActivity launchActivityWithIntentForTestCommon(Intent int ent) {
58 setActivityIntent(intent);
59 return getActivity();
60 }
61
62 @SuppressWarnings("deprecation")
63 @Override
64 public void runOnUiThreadForTestCommon(Runnable runnable) throws Throwable {
65 runTestOnUiThread(runnable);
66 }
67
68 @Override
69 @SuppressWarnings("deprecation")
60 protected void setUp() throws Exception { 70 protected void setUp() throws Exception {
61 super.setUp(); 71 super.setUp();
62 assertScreenIsOn(); 72 mDelegate.assertScreenIsOn();
63 }
64
65 @TargetApi(Build.VERSION_CODES.KITKAT_WATCH)
66 @SuppressWarnings("deprecation")
67 private void assertScreenIsOn() {
68 PowerManager pm = (PowerManager) getInstrumentation().getContext().getSy stemService(
69 Context.POWER_SERVICE);
70
71 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
72 assertTrue("Many tests will fail if the screen is not on.", pm.isInt eractive());
73 } else {
74 assertTrue("Many tests will fail if the screen is not on.", pm.isScr eenOn());
75 }
76 } 73 }
77 74
78 /** 75 /**
79 * Starts the ContentShell activity and loads the given URL. 76 * Starts the ContentShell activity and loads the given URL.
80 * The URL can be null, in which case will default to ContentShellActivity.D EFAULT_SHELL_URL. 77 * The URL can be null, in which case will default to ContentShellActivity.D EFAULT_SHELL_URL.
81 */ 78 */
82 protected ContentShellActivity launchContentShellWithUrl(String url) { 79 public ContentShellActivity launchContentShellWithUrl(String url) {
83 Intent intent = new Intent(Intent.ACTION_MAIN); 80 return mDelegate.launchContentShellWithUrl(url);
84 intent.addCategory(Intent.CATEGORY_LAUNCHER);
85 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
86 if (url != null) intent.setData(Uri.parse(url));
87 intent.setComponent(new ComponentName(getInstrumentation().getTargetCont ext(),
88 ContentShellActivity.class));
89 setActivityIntent(intent);
90 return getActivity();
91 } 81 }
92 82
93 // TODO(cjhopman): These functions are inconsistent with launchContentShell* **. Should be 83 // TODO(cjhopman): These functions are inconsistent with launchContentShell* **. Should be
94 // startContentShell*** and should use the url exactly without the getTestFi leUrl call. Possibly 84 // startContentShell*** and should use the url exactly without the getTestFi leUrl call. Possibly
95 // these two ways of starting the activity (launch* and start*) should be me rged into one. 85 // these two ways of starting the activity (launch* and start*) should be me rged into one.
96 /** 86 /**
97 * Starts the content shell activity with the provided test url. 87 * Starts the content shell activity with the provided test url.
98 * The url is synchronously loaded. 88 * The url is synchronously loaded.
99 * @param url Test url to load. 89 * @param url Test url to load.
100 */ 90 */
101 protected void startActivityWithTestUrl(String url) { 91 public void startActivityWithTestUrl(String url) {
102 launchContentShellWithUrl(UrlUtils.getIsolatedTestFileUrl(url)); 92 mDelegate.launchContentShellWithUrlSync(url);
103 assertNotNull(getActivity());
104 waitForActiveShellToBeDoneLoading();
105 assertEquals(UrlUtils.getIsolatedTestFileUrl(url),
106 getContentViewCore().getWebContents().getUrl());
107 } 93 }
108 94
109 /** 95 /**
110 * Returns the current ContentViewCore or null if there is no ContentView. 96 * Returns the current ContentViewCore or null if there is no ContentView.
111 */ 97 */
112 protected ContentViewCore getContentViewCore() { 98 public ContentViewCore getContentViewCore() {
113 return getActivity().getActiveShell().getContentViewCore(); 99 return mDelegate.getContentViewCore();
114 } 100 }
115 101
116 /** 102 /**
117 * Returns the WebContents of this Shell. 103 * Returns the WebContents of this Shell.
118 */ 104 */
119 protected WebContents getWebContents() { 105 public WebContents getWebContents() {
120 return getActivity().getActiveShell().getWebContents(); 106 return mDelegate.getWebContents();
121 } 107 }
122 108
123 /** 109 /**
124 * Waits for the Active shell to finish loading. This times out after 110 * Waits for the Active shell to finish loading. This times out after
125 * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be us ed for long 111 * WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT milliseconds and it shouldn't be us ed for long
126 * loading pages. Instead it should be used more for test initialization. Th e proper way 112 * loading pages. Instead it should be used more for test initialization. Th e proper way
127 * to wait is to use a TestCallbackHelperContainer after the initial load is completed. 113 * to wait is to use a TestCallbackHelperContainer after the initial load is completed.
128 */ 114 */
129 protected void waitForActiveShellToBeDoneLoading() { 115 public void waitForActiveShellToBeDoneLoading() {
130 final ContentShellActivity activity = getActivity(); 116 mDelegate.waitForActiveShellToBeDoneLoading();
131
132 // Wait for the Content Shell to be initialized.
133 CriteriaHelper.pollUiThread(new Criteria() {
134 @Override
135 public boolean isSatisfied() {
136 Shell shell = activity.getActiveShell();
137 // There are two cases here that need to be accounted for.
138 // The first is that we've just created a Shell and it isn't
139 // loading because it has no URL set yet. The second is that
140 // we've set a URL and it actually is loading.
141 if (shell == null) {
142 updateFailureReason("Shell is null.");
143 return false;
144 }
145 if (shell.isLoading()) {
146 updateFailureReason("Shell is still loading.");
147 return false;
148 }
149 if (TextUtils.isEmpty(shell.getContentViewCore().getWebContents( ).getUrl())) {
150 updateFailureReason("Shell's URL is empty or null.");
151 return false;
152 }
153 return true;
154 }
155 }, WAIT_FOR_ACTIVE_SHELL_LOADING_TIMEOUT, CriteriaHelper.DEFAULT_POLLING _INTERVAL);
156 } 117 }
157 118
158 /** 119 /**
159 * Creates a new {@link Shell} and waits for it to finish loading. 120 * Creates a new {@link Shell} and waits for it to finish loading.
160 * @param url The URL to create the new {@link Shell} with. 121 * @param url The URL to create the new {@link Shell} with.
161 * @return A new instance of a {@link Shell}. 122 * @return A new instance of a {@link Shell}.
162 * @throws ExecutionException 123 * @throws ExecutionException
163 */ 124 */
164 protected Shell loadNewShell(final String url) throws ExecutionException { 125 public Shell loadNewShell(String url) throws ExecutionException {
165 Shell shell = ThreadUtils.runOnUiThreadBlocking(new Callable<Shell>() { 126 return mDelegate.loadNewShell(url);
166 @Override 127 }
167 public Shell call() {
168 getActivity().getShellManager().launchShell(url);
169 return getActivity().getActiveShell();
170 }
171 });
172 128
173 assertNotNull("Unable to create shell.", shell);
174 assertEquals("Active shell unexpected.", shell, getActivity().getActiveS hell());
175
176 waitForActiveShellToBeDoneLoading();
177
178 return shell;
179 }
180 /** 129 /**
181 * Loads a URL in the specified content view. 130 * Loads a URL in the specified content view.
182 * 131 *
183 * @param navigationController The navigation controller to load the URL in. 132 * @param navigationController The navigation controller to load the URL in.
184 * @param callbackHelperContainer The callback helper container used to moni tor progress. 133 * @param callbackHelperContainer The callback helper container used to moni tor progress.
185 * @param params The URL params to use. 134 * @param params The URL params to use.
186 */ 135 */
187 protected void loadUrl( 136 public void loadUrl(NavigationController navigationController,
188 final NavigationController navigationController, 137 TestCallbackHelperContainer callbackHelperContainer, LoadUrlParams p arams)
189 TestCallbackHelperContainer callbackHelperContainer, 138 throws Throwable {
190 final LoadUrlParams params) throws Throwable { 139 mDelegate.loadUrl(navigationController, callbackHelperContainer, params) ;
191 handleBlockingCallbackAction(
192 callbackHelperContainer.getOnPageFinishedHelper(),
193 new Runnable() {
194 @Override
195 public void run() {
196 navigationController.loadUrl(params);
197 }
198 });
199 } 140 }
200 141
201 /** 142 /**
202 * Handles performing an action on the UI thread that will return when the s pecified callback 143 * Handles performing an action on the UI thread that will return when the s pecified callback
203 * is incremented. 144 * is incremented.
204 * 145 *
205 * @param callbackHelper The callback helper that will be blocked on. 146 * @param callbackHelper The callback helper that will be blocked on.
206 * @param action The action to be performed on the UI thread. 147 * @param action The action to be performed on the UI thread.
207 */ 148 */
208 protected void handleBlockingCallbackAction( 149 public void handleBlockingCallbackAction(CallbackHelper callbackHelper, Runn able action)
209 CallbackHelper callbackHelper, Runnable action) throws Throwable { 150 throws Throwable {
210 int currentCallCount = callbackHelper.getCallCount(); 151 mDelegate.handleBlockingCallbackAction(callbackHelper, action);
211 runTestOnUiThread(action);
212 callbackHelper.waitForCallback(
213 currentCallCount, 1, WAIT_PAGE_LOADING_TIMEOUT_SECONDS, TimeUnit .SECONDS);
214 } 152 }
215 153
216 // TODO(aelias): This method needs to be removed once http://crbug.com/17951 1 is fixed. 154 // TODO(aelias): This method needs to be removed once http://crbug.com/17951 1 is fixed.
217 // Meanwhile, we have to wait if the page has the <meta viewport> tag. 155 // Meanwhile, we have to wait if the page has the <meta viewport> tag.
218 /** 156 /**
219 * Waits till the ContentViewCore receives the expected page scale factor 157 * Waits till the ContentViewCore receives the expected page scale factor
220 * from the compositor and asserts that this happens. 158 * from the compositor and asserts that this happens.
221 */ 159 */
222 protected void assertWaitForPageScaleFactorMatch(float expectedScale) { 160 public void assertWaitForPageScaleFactorMatch(float expectedScale) {
223 CriteriaHelper.pollInstrumentationThread( 161 mDelegate.assertWaitForPageScaleFactorMatch(expectedScale);
224 Criteria.equals(expectedScale, new Callable<Float>() {
225 @Override
226 public Float call() {
227 return getContentViewCore().getScale();
228 }
229 }));
230 } 162 }
231 163
232 /** 164 /**
233 * Replaces the {@link ContentViewCore#mContainerView} with a newly created 165 * Replaces the {@link ContentViewCore#mContainerView} with a newly created
234 * {@link ContentView}. 166 * {@link ContentView}.
235 */ 167 */
236 @SuppressWarnings("javadoc") 168 @SuppressWarnings("javadoc")
237 protected void replaceContainerView() throws Throwable { 169 public void replaceContainerView() throws Throwable {
238 ThreadUtils.runOnUiThreadBlocking(new Runnable() { 170 mDelegate.replaceContainerView();
239 @Override
240 public void run() {
241 ContentView cv = ContentView.createContentView(getActivity(), ge tContentViewCore());
242 ((ViewGroup) getContentViewCore().getContainerView().getParent() ).addView(cv);
243 getContentViewCore().setContainerView(cv);
244 getContentViewCore().setContainerViewInternals(cv);
245 cv.requestFocus();
246 }
247 });
248 } 171 }
249 172
173 @SuppressWarnings("deprecation")
250 @Override 174 @Override
251 protected void runTest() throws Throwable { 175 protected void runTest() throws Throwable {
252 super.runTest(); 176 super.runTest();
253 try { 177 try {
254 AnnotatedElement method = getClass().getMethod(getName(), (Class[]) null); 178 AnnotatedElement method = getClass().getMethod(getName(), (Class[]) null);
255 if (method.isAnnotationPresent(RerunWithUpdatedContainerView.class)) { 179 if (method.isAnnotationPresent(RerunWithUpdatedContainerView.class)) {
256 replaceContainerView(); 180 replaceContainerView();
257 super.runTest(); 181 super.runTest();
258 } 182 }
259 } catch (Throwable e) { 183 } catch (Throwable e) {
260 throw new Throwable("@RerunWithUpdatedContainerView failed." 184 throw new Throwable("@RerunWithUpdatedContainerView failed."
261 + " See ContentShellTestBase#runTest.", e); 185 + " See ContentShellTestBase#runTest.", e);
262 } 186 }
263 } 187 }
264
265 /**
266 * Annotation for tests that should be executed a second time after replacin g
267 * the ContentViewCore's container view (see {@link #runTest()}).
268 *
269 * <p>Please note that {@link #setUp()} is only invoked once before both run s,
270 * and that any state changes produced by the first run are visible to the s econd run.
271 */
272 @Target(ElementType.METHOD)
273 @Retention(RetentionPolicy.RUNTIME)
274 public @interface RerunWithUpdatedContainerView {
275 }
276 } 188 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698