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

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

Powered by Google App Engine
This is Rietveld 408576698