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.XWalkView;
32 import org.xwalk.core.internal.XWalkClient;
33 import org.xwalk.core.internal.XWalkSettings;
34 import org.xwalk.core.internal.XWalkViewInternal;
35 import org.xwalk.core.internal.XWalkWebChromeClient;
37 public class XWalkViewTestBase
38 extends ActivityInstrumentationTestCase2<XWalkViewTestRunnerActivity> {
39 protected final static int WAIT_TIMEOUT_SECONDS = 15;
40 private final static String TAG = "XWalkViewTestBase";
41 private XWalkView mXWalkView;
42 final TestHelperBridge mTestHelperBridge = new TestHelperBridge();
44 class TestXWalkClientBase extends XWalkClient {
45 TestHelperBridge mInnerContentsClient;
46 public TestXWalkClientBase(TestHelperBridge client) {
47 super(getXWalkView());
48 mInnerContentsClient = client;
52 public void onPageStarted(XWalkViewInternal view, String url) {
53 mInnerContentsClient.onPageStarted(url);
57 public void onPageFinished(XWalkViewInternal view, String url) {
58 mInnerContentsClient.onPageFinished(url);
62 class TestXWalkClient extends TestXWalkClientBase {
63 public TestXWalkClient() {
64 super(mTestHelperBridge);
68 class TestXWalkWebChromeClientBase extends XWalkWebChromeClient {
69 TestHelperBridge mInnerContentsClient;
70 public TestXWalkWebChromeClientBase(TestHelperBridge client) {
71 super(getXWalkView());
72 mInnerContentsClient = client;
76 public void onReceivedTitle(XWalkViewInternal view, String title) {
77 mInnerContentsClient.onTitleChanged(title);
81 class TestXWalkWebChromeClient extends TestXWalkWebChromeClientBase {
82 public TestXWalkWebChromeClient() {
83 super(mTestHelperBridge);
87 class TestXWalkResourceClientBase extends XWalkResourceClient {
88 TestHelperBridge mInnerContentsClient;
89 public TestXWalkResourceClientBase(TestHelperBridge client) {
91 mInnerContentsClient = client;
95 public void onLoadStarted(XWalkView view, String url) {
96 mTestHelperBridge.onLoadStarted(url);
100 public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
101 mTestHelperBridge.onReceivedLoadError(errorCode, description, failingUrl);
105 public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
107 return mTestHelperBridge.shouldInterceptLoadRequest(url);
111 class TestXWalkResourceClient extends TestXWalkResourceClientBase {
112 public TestXWalkResourceClient() {
113 super(mTestHelperBridge);
117 void setXWalkClient(final XWalkClient client) {
118 getInstrumentation().runOnMainSync(new Runnable() {
121 getXWalkView().setXWalkClient(client);
126 void setXWalkWebChromeClient(final XWalkWebChromeClient client) {
127 getInstrumentation().runOnMainSync(new Runnable() {
130 getXWalkView().setXWalkWebChromeClient(client);
135 void setResourceClient(final XWalkResourceClient client) {
136 getInstrumentation().runOnMainSync(new Runnable() {
139 getXWalkView().setResourceClient(client);
144 static class ViewPair {
145 private final XWalkView content0;
146 private final TestHelperBridge client0;
147 private final XWalkView content1;
148 private final TestHelperBridge client1;
150 ViewPair(XWalkView content0, TestHelperBridge client0,
151 XWalkView content1, TestHelperBridge client1) {
152 this.content0 = content0;
153 this.client0 = client0;
154 this.content1 = content1;
155 this.client1 = client1;
158 XWalkView getContent0() {
162 TestHelperBridge getClient0() {
166 XWalkView getContent1() {
170 TestHelperBridge getClient1() {
175 public XWalkViewTestBase() {
176 super(XWalkViewTestRunnerActivity.class);
180 protected void setUp() throws Exception {
183 // Must call getActivity() here but not in main thread.
184 final Activity activity = getActivity();
185 getInstrumentation().runOnMainSync(new Runnable() {
188 mXWalkView = new XWalkView(activity, activity);
189 getActivity().addView(mXWalkView);
190 // mXWalkView.getXWalkViewContentForTest().installWebContentsObserverForTest(mTestHelperBridge);
195 protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
196 return CriteriaHelper.pollForCriteria(new Criteria() {
198 public boolean isSatisfied() {
200 return runTestOnUiThreadAndGetResult(callable);
201 } catch (Throwable e) {
208 protected void loadJavaScriptUrl(final String url) throws Exception {
209 if (!url.startsWith("javascript:")) {
210 Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
216 protected void loadUrlSync(final String url) throws Exception {
217 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
218 int currentCallCount = pageFinishedHelper.getCallCount();
221 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
225 protected void loadUrlAsync(final String url) throws Exception {
226 getInstrumentation().runOnMainSync(new Runnable() {
229 mXWalkView.load(url, null);
234 protected void loadDataSync(final String url, final String data, final String mimeType,
235 final boolean isBase64Encoded) throws Exception {
236 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
237 int currentCallCount = pageFinishedHelper.getCallCount();
238 loadDataAsync(url, data, mimeType, isBase64Encoded);
239 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
243 protected void loadDataAsync(final String url, final String data, final String mimeType,
244 final boolean isBase64Encoded) throws Exception {
245 getInstrumentation().runOnMainSync(new Runnable() {
248 mXWalkView.load(url, data);
253 protected void loadUrlSyncByContent(final XWalkView xWalkContent,
254 final TestHelperBridge contentsClient,
255 final String url) throws Exception {
256 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
257 int currentCallCount = pageFinishedHelper.getCallCount();
258 loadUrlAsyncByContent(xWalkContent, url);
260 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
264 protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
265 final String url) throws Exception {
266 getInstrumentation().runOnMainSync(new Runnable() {
269 xWalkContent.load(url, null);
274 protected String getTitleOnUiThread() throws Exception {
275 return runTestOnUiThreadAndGetResult(new Callable<String>() {
277 public String call() throws Exception {
278 return mXWalkView.getTitle();
283 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
285 FutureTask<R> task = new FutureTask<R>(callable);
286 getInstrumentation().waitForIdleSync();
287 getInstrumentation().runOnMainSync(task);
291 protected String getFileContent(String fileName) {
293 Context context = getInstrumentation().getContext();
294 InputStream inputStream = context.getAssets().open(fileName);
295 int size = inputStream.available();
296 byte buffer[] = new byte[size];
297 inputStream.read(buffer);
300 String fileContent = new String(buffer);
302 } catch (IOException e) {
303 throw new RuntimeException(e);
307 protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
308 return runTestOnUiThreadAndGetResult(new Callable<String>() {
310 public String call() throws Exception {
311 String title = xWalkContent.getTitle();
317 protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
318 final XWalkView xwalkContent) throws Exception {
319 return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
321 public XWalkSettings call() throws Exception {
322 return xwalkContent.getSettings();
327 protected XWalkView createXWalkViewContainerOnMainSync(
328 final Context context,
329 final XWalkClient client,
330 final XWalkResourceClient resourceClient,
331 final XWalkWebChromeClient webChromeClient) throws Exception {
332 final AtomicReference<XWalkView> xWalkViewContainer =
333 new AtomicReference<XWalkView>();
334 getInstrumentation().runOnMainSync(new Runnable() {
337 xWalkViewContainer.set(new XWalkView(context, getActivity()));
338 getActivity().addView(xWalkViewContainer.get());
339 xWalkViewContainer.get().setXWalkClient(client);
340 xWalkViewContainer.get().setResourceClient(resourceClient);
341 xWalkViewContainer.get().setXWalkWebChromeClient(webChromeClient);
345 return xWalkViewContainer.get();
348 protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
349 final TestHelperBridge helperBridge1,
350 final XWalkClient client0,
351 final XWalkClient client1,
352 final XWalkResourceClient resourceClient0,
353 final XWalkResourceClient resourceClient1,
354 final XWalkWebChromeClient chromeClient0,
355 final XWalkWebChromeClient chromeClient1,
356 final Context context) throws Throwable {
357 final XWalkView walkView0 = createXWalkViewContainerOnMainSync(context,
358 client0, resourceClient0, chromeClient0);
359 final XWalkView walkView1 = createXWalkViewContainerOnMainSync(context,
360 client1, resourceClient1, chromeClient1);
361 final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
363 getInstrumentation().runOnMainSync(new Runnable() {
366 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
370 return viewPair.get();
373 protected void loadAssetFile(String fileName) throws Exception {
374 String fileContent = getFileContent(fileName);
375 loadDataSync(fileName, fileContent, "text/html", false);
378 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
379 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
380 int currentCallCount = getTitleHelper.getCallCount();
381 String fileContent = getFileContent(fileName);
383 loadDataSync(fileName, fileContent, "text/html", false);
385 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
389 protected XWalkView getXWalkView() {
393 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
394 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
395 int currentCallCount = pageFinishedHelper.getCallCount();
397 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
401 protected void reloadSync(final int mode) throws Exception {
402 runTestWaitPageFinished(new Runnable(){
405 getInstrumentation().runOnMainSync(new Runnable() {
408 mXWalkView.reload(mode);
415 protected void goBackSync() throws Throwable {
416 runTestWaitPageFinished(new Runnable(){
419 getInstrumentation().runOnMainSync(new Runnable() {
422 mXWalkView.getNavigationHistory().navigate(
423 XWalkNavigationHistory.Direction.BACKWARD, 1);
430 protected void goForwardSync() throws Throwable {
431 runTestWaitPageFinished(new Runnable(){
434 getInstrumentation().runOnMainSync(new Runnable() {
437 mXWalkView.getNavigationHistory().navigate(
438 XWalkNavigationHistory.Direction.FORWARD, 1);
445 protected void clearHistoryOnUiThread() throws Exception {
446 getInstrumentation().runOnMainSync(new Runnable() {
449 mXWalkView.getNavigationHistory().clear();
454 protected boolean canGoBackOnUiThread() throws Throwable {
455 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
457 public Boolean call() {
458 return mXWalkView.getNavigationHistory().canGoBack();
463 protected boolean canGoForwardOnUiThread() throws Throwable {
464 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
466 public Boolean call() {
467 return mXWalkView.getNavigationHistory().canGoForward();
472 protected int historySizeOnUiThread() throws Throwable {
473 return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
475 public Integer call() {
476 return mXWalkView.getNavigationHistory().size();
481 protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
482 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
484 public Boolean call() {
485 return mXWalkView.getNavigationHistory().hasItemAt(index);
490 protected XWalkNavigationItem getItemAtOnUiThread(final int index) throws Throwable {
491 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
493 public XWalkNavigationItem call() {
494 return mXWalkView.getNavigationHistory().getItemAt(index);
499 protected XWalkNavigationItem getCurrentItemOnUiThread() throws Throwable {
500 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
502 public XWalkNavigationItem call() {
503 return mXWalkView.getNavigationHistory().getCurrentItem();
508 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
510 final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
511 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
512 getInstrumentation().runOnMainSync(new Runnable() {
515 helper.evaluateJavascript(mXWalkView, code);
518 helper.waitUntilHasValue();
519 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
520 return helper.getJsonResultAndClear();
523 protected ViewPair createViews() throws Throwable {
524 TestHelperBridge helperBridge0 = new TestHelperBridge();
525 TestHelperBridge helperBridge1 = new TestHelperBridge();
526 TestXWalkClientBase viewClient0 = new TestXWalkClientBase(helperBridge0);
527 TestXWalkClientBase viewClient1 = new TestXWalkClientBase(helperBridge1);
528 TestXWalkWebChromeClientBase chromeClient0 =
529 new TestXWalkWebChromeClientBase(helperBridge0);
530 TestXWalkWebChromeClientBase chromeClient1 =
531 new TestXWalkWebChromeClientBase(helperBridge1);
532 TestXWalkResourceClientBase resourceClient0 =
533 new TestXWalkResourceClientBase(helperBridge0);
534 TestXWalkResourceClientBase resourceClient1 =
535 new TestXWalkResourceClientBase(helperBridge1);
537 createViewsOnMainSync(helperBridge0, helperBridge1, viewClient0, viewClient1,
538 resourceClient0, resourceClient1, chromeClient0, chromeClient1,
544 protected String getUrlOnUiThread() throws Exception {
545 return runTestOnUiThreadAndGetResult(new Callable<String>() {
547 public String call() throws Exception {
548 return mXWalkView.getUrl();
553 protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
554 getInstrumentation().runOnMainSync(new Runnable() {
557 mXWalkView.clearCache(includeDiskFiles);
562 protected String getAPIVersionOnUiThread() throws Exception {
563 return runTestOnUiThreadAndGetResult(new Callable<String>() {
565 public String call() throws Exception {
566 return mXWalkView.getAPIVersion();
571 protected String getXWalkVersionOnUiThread() throws Exception {
572 return runTestOnUiThreadAndGetResult(new Callable<String>() {
574 public String call() throws Exception {
575 return mXWalkView.getXWalkVersion();