1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Copyright (c) 2013-2014 Intel Corporation. All rights reserved.
3 // Use of this source code is governed by a BSD-style license that can be
4 // found in the LICENSE file.
6 package org.xwalk.core.xwview.test;
8 import android.app.Activity;
9 import android.content.Context;
10 import android.test.ActivityInstrumentationTestCase2;
11 import android.util.Log;
12 import android.webkit.WebResourceResponse;
14 import java.io.InputStream;
15 import java.io.IOException;
16 import java.util.concurrent.atomic.AtomicReference;
17 import java.util.concurrent.Callable;
18 import java.util.concurrent.FutureTask;
19 import java.util.concurrent.TimeUnit;
21 import junit.framework.Assert;
23 import org.chromium.content.browser.LoadUrlParams;
24 import org.chromium.content.browser.test.util.CallbackHelper;
25 import org.chromium.content.browser.test.util.Criteria;
26 import org.chromium.content.browser.test.util.CriteriaHelper;
28 import org.xwalk.core.XWalkNavigationHistory;
29 import org.xwalk.core.XWalkNavigationItem;
30 import org.xwalk.core.XWalkResourceClient;
31 import org.xwalk.core.XWalkUIClient;
32 import org.xwalk.core.XWalkView;
33 import org.xwalk.core.internal.XWalkSettings;
35 public class XWalkViewTestBase
36 extends ActivityInstrumentationTestCase2<XWalkViewTestRunnerActivity> {
37 protected final static int WAIT_TIMEOUT_SECONDS = 15;
38 private final static String TAG = "XWalkViewTestBase";
39 private XWalkView mXWalkView;
40 final TestHelperBridge mTestHelperBridge = new TestHelperBridge();
42 class TestXWalkUIClientBase extends XWalkUIClient {
43 TestHelperBridge mInnerContentsClient;
44 public TestXWalkUIClientBase(TestHelperBridge client) {
45 super(getXWalkView());
46 mInnerContentsClient = client;
50 public void onPageLoadStarted(XWalkView view, String url) {
51 mInnerContentsClient.onPageStarted(url);
55 public void onPageLoadStopped(XWalkView view, String url, LoadStatus status) {
56 mInnerContentsClient.onPageFinished(url);
60 public void onReceivedTitle(XWalkView view, String title) {
61 mInnerContentsClient.onTitleChanged(title);
65 class TestXWalkUIClient extends TestXWalkUIClientBase {
66 public TestXWalkUIClient() {
67 super(mTestHelperBridge);
71 class TestXWalkResourceClientBase extends XWalkResourceClient {
72 TestHelperBridge mInnerContentsClient;
73 public TestXWalkResourceClientBase(TestHelperBridge client) {
75 mInnerContentsClient = client;
79 public void onLoadStarted(XWalkView view, String url) {
80 mInnerContentsClient.onLoadStarted(url);
84 public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
85 mInnerContentsClient.onReceivedLoadError(errorCode, description, failingUrl);
89 public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
91 return mInnerContentsClient.shouldInterceptLoadRequest(url);
95 class TestXWalkResourceClient extends TestXWalkResourceClientBase {
96 public TestXWalkResourceClient() {
97 super(mTestHelperBridge);
101 void setUIClient(final XWalkUIClient client) {
102 getInstrumentation().runOnMainSync(new Runnable() {
105 getXWalkView().setUIClient(client);
110 void setResourceClient(final XWalkResourceClient client) {
111 getInstrumentation().runOnMainSync(new Runnable() {
114 getXWalkView().setResourceClient(client);
119 static class ViewPair {
120 private final XWalkView content0;
121 private final TestHelperBridge client0;
122 private final XWalkView content1;
123 private final TestHelperBridge client1;
125 ViewPair(XWalkView content0, TestHelperBridge client0,
126 XWalkView content1, TestHelperBridge client1) {
127 this.content0 = content0;
128 this.client0 = client0;
129 this.content1 = content1;
130 this.client1 = client1;
133 XWalkView getContent0() {
137 TestHelperBridge getClient0() {
141 XWalkView getContent1() {
145 TestHelperBridge getClient1() {
150 public XWalkViewTestBase() {
151 super(XWalkViewTestRunnerActivity.class);
155 protected void setUp() throws Exception {
158 // Must call getActivity() here but not in main thread.
159 final Activity activity = getActivity();
160 getInstrumentation().runOnMainSync(new Runnable() {
163 mXWalkView = new XWalkView(activity, activity);
164 getActivity().addView(mXWalkView);
165 mXWalkView.setUIClient(new TestXWalkUIClient());
166 mXWalkView.setResourceClient(new TestXWalkResourceClient());
167 // mXWalkView.getXWalkViewContentForTest().installWebContentsObserverForTest(mTestHelperBridge);
172 protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
173 return CriteriaHelper.pollForCriteria(new Criteria() {
175 public boolean isSatisfied() {
177 return runTestOnUiThreadAndGetResult(callable);
178 } catch (Throwable e) {
185 protected void loadJavaScriptUrl(final String url) throws Exception {
186 if (!url.startsWith("javascript:")) {
187 Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
193 protected void loadUrlSync(final String url) throws Exception {
194 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
195 int currentCallCount = pageFinishedHelper.getCallCount();
198 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
202 protected void loadUrlAsync(final String url) throws Exception {
203 getInstrumentation().runOnMainSync(new Runnable() {
206 mXWalkView.load(url, null);
211 protected void loadDataSync(final String url, final String data, final String mimeType,
212 final boolean isBase64Encoded) throws Exception {
213 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
214 int currentCallCount = pageFinishedHelper.getCallCount();
215 loadDataAsync(url, data, mimeType, isBase64Encoded);
216 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
220 protected void loadDataAsync(final String url, final String data, final String mimeType,
221 final boolean isBase64Encoded) throws Exception {
222 getInstrumentation().runOnMainSync(new Runnable() {
225 mXWalkView.load(url, data);
230 protected void loadUrlSyncByContent(final XWalkView xWalkContent,
231 final TestHelperBridge contentsClient,
232 final String url) throws Exception {
233 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
234 int currentCallCount = pageFinishedHelper.getCallCount();
235 loadUrlAsyncByContent(xWalkContent, url);
237 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
241 protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
242 final String url) throws Exception {
243 getInstrumentation().runOnMainSync(new Runnable() {
246 xWalkContent.load(url, null);
251 protected String getTitleOnUiThread() throws Exception {
252 return runTestOnUiThreadAndGetResult(new Callable<String>() {
254 public String call() throws Exception {
255 return mXWalkView.getTitle();
260 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
262 FutureTask<R> task = new FutureTask<R>(callable);
263 getInstrumentation().waitForIdleSync();
264 getInstrumentation().runOnMainSync(task);
268 protected String getFileContent(String fileName) {
270 Context context = getInstrumentation().getContext();
271 InputStream inputStream = context.getAssets().open(fileName);
272 int size = inputStream.available();
273 byte buffer[] = new byte[size];
274 inputStream.read(buffer);
277 String fileContent = new String(buffer);
279 } catch (IOException e) {
280 throw new RuntimeException(e);
284 protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
285 return runTestOnUiThreadAndGetResult(new Callable<String>() {
287 public String call() throws Exception {
288 String title = xWalkContent.getTitle();
294 protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
295 final XWalkView xwalkContent) throws Exception {
296 return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
298 public XWalkSettings call() throws Exception {
299 return xwalkContent.getSettings();
304 protected XWalkView createXWalkViewContainerOnMainSync(
305 final Context context,
306 final XWalkUIClient uiClient,
307 final XWalkResourceClient resourceClient) throws Exception {
308 final AtomicReference<XWalkView> xWalkViewContainer =
309 new AtomicReference<XWalkView>();
310 getInstrumentation().runOnMainSync(new Runnable() {
313 xWalkViewContainer.set(new XWalkView(context, getActivity()));
314 getActivity().addView(xWalkViewContainer.get());
315 xWalkViewContainer.get().setUIClient(uiClient);
316 xWalkViewContainer.get().setResourceClient(resourceClient);
320 return xWalkViewContainer.get();
323 protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
324 final TestHelperBridge helperBridge1,
325 final XWalkUIClient uiClient0,
326 final XWalkUIClient uiClient1,
327 final XWalkResourceClient resourceClient0,
328 final XWalkResourceClient resourceClient1,
329 final Context context) throws Throwable {
330 final XWalkView walkView0 = createXWalkViewContainerOnMainSync(context,
331 uiClient0, resourceClient0);
332 final XWalkView walkView1 = createXWalkViewContainerOnMainSync(context,
333 uiClient1, resourceClient1);
334 final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
336 getInstrumentation().runOnMainSync(new Runnable() {
339 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
343 return viewPair.get();
346 protected void loadAssetFile(String fileName) throws Exception {
347 String fileContent = getFileContent(fileName);
348 loadDataSync(fileName, fileContent, "text/html", false);
351 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
352 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
353 int currentCallCount = getTitleHelper.getCallCount();
354 String fileContent = getFileContent(fileName);
356 loadDataSync(fileName, fileContent, "text/html", false);
358 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
362 protected XWalkView getXWalkView() {
366 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
367 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
368 int currentCallCount = pageFinishedHelper.getCallCount();
370 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
374 protected void reloadSync(final int mode) throws Exception {
375 runTestWaitPageFinished(new Runnable(){
378 getInstrumentation().runOnMainSync(new Runnable() {
381 mXWalkView.reload(mode);
388 protected void goBackSync() throws Throwable {
389 runTestWaitPageFinished(new Runnable(){
392 getInstrumentation().runOnMainSync(new Runnable() {
395 mXWalkView.getNavigationHistory().navigate(
396 XWalkNavigationHistory.Direction.BACKWARD, 1);
403 protected void goForwardSync() throws Throwable {
404 runTestWaitPageFinished(new Runnable(){
407 getInstrumentation().runOnMainSync(new Runnable() {
410 mXWalkView.getNavigationHistory().navigate(
411 XWalkNavigationHistory.Direction.FORWARD, 1);
418 protected void clearHistoryOnUiThread() throws Exception {
419 getInstrumentation().runOnMainSync(new Runnable() {
422 mXWalkView.getNavigationHistory().clear();
427 protected boolean canGoBackOnUiThread() throws Throwable {
428 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
430 public Boolean call() {
431 return mXWalkView.getNavigationHistory().canGoBack();
436 protected boolean canGoForwardOnUiThread() throws Throwable {
437 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
439 public Boolean call() {
440 return mXWalkView.getNavigationHistory().canGoForward();
445 protected int historySizeOnUiThread() throws Throwable {
446 return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
448 public Integer call() {
449 return mXWalkView.getNavigationHistory().size();
454 protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
455 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
457 public Boolean call() {
458 return mXWalkView.getNavigationHistory().hasItemAt(index);
463 protected XWalkNavigationItem getItemAtOnUiThread(final int index) throws Throwable {
464 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
466 public XWalkNavigationItem call() {
467 return mXWalkView.getNavigationHistory().getItemAt(index);
472 protected XWalkNavigationItem getCurrentItemOnUiThread() throws Throwable {
473 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
475 public XWalkNavigationItem call() {
476 return mXWalkView.getNavigationHistory().getCurrentItem();
481 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
483 final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
484 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
485 getInstrumentation().runOnMainSync(new Runnable() {
488 helper.evaluateJavascript(mXWalkView, code);
491 helper.waitUntilHasValue();
492 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
493 return helper.getJsonResultAndClear();
496 protected ViewPair createViews() throws Throwable {
497 TestHelperBridge helperBridge0 = new TestHelperBridge();
498 TestHelperBridge helperBridge1 = new TestHelperBridge();
499 TestXWalkUIClientBase uiClient0 = new TestXWalkUIClientBase(helperBridge0);
500 TestXWalkUIClientBase uiClient1 = new TestXWalkUIClientBase(helperBridge1);
501 TestXWalkResourceClientBase resourceClient0 =
502 new TestXWalkResourceClientBase(helperBridge0);
503 TestXWalkResourceClientBase resourceClient1 =
504 new TestXWalkResourceClientBase(helperBridge1);
506 createViewsOnMainSync(helperBridge0, helperBridge1, uiClient0, uiClient1,
507 resourceClient0, resourceClient1, getActivity());
512 protected String getUrlOnUiThread() throws Exception {
513 return runTestOnUiThreadAndGetResult(new Callable<String>() {
515 public String call() throws Exception {
516 return mXWalkView.getUrl();
521 protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
522 getInstrumentation().runOnMainSync(new Runnable() {
525 mXWalkView.clearCache(includeDiskFiles);
530 protected String getAPIVersionOnUiThread() throws Exception {
531 return runTestOnUiThreadAndGetResult(new Callable<String>() {
533 public String call() throws Exception {
534 return mXWalkView.getAPIVersion();
539 protected String getXWalkVersionOnUiThread() throws Exception {
540 return runTestOnUiThreadAndGetResult(new Callable<String>() {
542 public String call() throws Exception {
543 return mXWalkView.getXWalkVersion();