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

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

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

Powered by Google App Engine
This is Rietveld 408576698