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.XWalkClient;
29 import org.xwalk.core.XWalkNavigationHistory;
30 import org.xwalk.core.XWalkNavigationItem;
31 import org.xwalk.core.XWalkResourceClient;
32 import org.xwalk.core.XWalkSettings;
33 import org.xwalk.core.XWalkView;
34 import org.xwalk.core.XWalkWebChromeClient;
36 public class XWalkViewTestBase
37 extends ActivityInstrumentationTestCase2<XWalkViewTestRunnerActivity> {
38 protected final static int WAIT_TIMEOUT_SECONDS = 15;
39 private final static String TAG = "XWalkViewTestBase";
40 private XWalkView mXWalkView;
41 final TestHelperBridge mTestHelperBridge = new TestHelperBridge();
43 class TestXWalkClientBase extends XWalkClient {
44 TestHelperBridge mInnerContentsClient;
45 public TestXWalkClientBase(TestHelperBridge client) {
46 super(getXWalkView());
47 mInnerContentsClient = client;
51 public void onPageStarted(XWalkView view, String url) {
52 mInnerContentsClient.onPageStarted(url);
56 public void onPageFinished(XWalkView view, String url) {
57 mInnerContentsClient.onPageFinished(url);
61 class TestXWalkClient extends TestXWalkClientBase {
62 public TestXWalkClient() {
63 super(mTestHelperBridge);
67 class TestXWalkWebChromeClientBase extends XWalkWebChromeClient {
68 TestHelperBridge mInnerContentsClient;
69 public TestXWalkWebChromeClientBase(TestHelperBridge client) {
70 super(getXWalkView());
71 mInnerContentsClient = client;
75 public void onReceivedTitle(XWalkView view, String title) {
76 mInnerContentsClient.onTitleChanged(title);
80 class TestXWalkWebChromeClient extends TestXWalkWebChromeClientBase {
81 public TestXWalkWebChromeClient() {
82 super(mTestHelperBridge);
86 class TestXWalkResourceClientBase extends XWalkResourceClient {
87 TestHelperBridge mInnerContentsClient;
88 public TestXWalkResourceClientBase(TestHelperBridge client) {
90 mInnerContentsClient = client;
94 public void onLoadStarted(XWalkView view, String url) {
95 mTestHelperBridge.onLoadStarted(url);
99 public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
100 mTestHelperBridge.onReceivedLoadError(errorCode, description, failingUrl);
104 public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
106 return mTestHelperBridge.shouldInterceptLoadRequest(url);
110 class TestXWalkResourceClient extends TestXWalkResourceClientBase {
111 public TestXWalkResourceClient() {
112 super(mTestHelperBridge);
116 void setXWalkClient(final XWalkClient client) {
117 getInstrumentation().runOnMainSync(new Runnable() {
120 getXWalkView().setXWalkClient(client);
125 void setXWalkWebChromeClient(final XWalkWebChromeClient client) {
126 getInstrumentation().runOnMainSync(new Runnable() {
129 getXWalkView().setXWalkWebChromeClient(client);
134 void setResourceClient(final XWalkResourceClient client) {
135 getInstrumentation().runOnMainSync(new Runnable() {
138 getXWalkView().setResourceClient(client);
143 static class ViewPair {
144 private final XWalkView content0;
145 private final TestHelperBridge client0;
146 private final XWalkView content1;
147 private final TestHelperBridge client1;
149 ViewPair(XWalkView content0, TestHelperBridge client0,
150 XWalkView content1, TestHelperBridge client1) {
151 this.content0 = content0;
152 this.client0 = client0;
153 this.content1 = content1;
154 this.client1 = client1;
157 XWalkView getContent0() {
161 TestHelperBridge getClient0() {
165 XWalkView getContent1() {
169 TestHelperBridge getClient1() {
174 public XWalkViewTestBase() {
175 super(XWalkViewTestRunnerActivity.class);
179 protected void setUp() throws Exception {
182 // Must call getActivity() here but not in main thread.
183 final Activity activity = getActivity();
184 getInstrumentation().runOnMainSync(new Runnable() {
187 mXWalkView = new XWalkView(activity, activity);
188 getActivity().addView(mXWalkView);
189 // mXWalkView.getXWalkViewContentForTest().installWebContentsObserverForTest(mTestHelperBridge);
194 protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
195 return CriteriaHelper.pollForCriteria(new Criteria() {
197 public boolean isSatisfied() {
199 return runTestOnUiThreadAndGetResult(callable);
200 } catch (Throwable e) {
207 protected void loadJavaScriptUrl(final String url) throws Exception {
208 if (!url.startsWith("javascript:")) {
209 Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
215 protected void loadUrlSync(final String url) throws Exception {
216 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
217 int currentCallCount = pageFinishedHelper.getCallCount();
220 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
224 protected void loadUrlAsync(final String url) throws Exception {
225 getInstrumentation().runOnMainSync(new Runnable() {
228 mXWalkView.load(url, null);
233 protected void loadDataSync(final String url, final String data, final String mimeType,
234 final boolean isBase64Encoded) throws Exception {
235 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
236 int currentCallCount = pageFinishedHelper.getCallCount();
237 loadDataAsync(url, data, mimeType, isBase64Encoded);
238 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
242 protected void loadDataAsync(final String url, final String data, final String mimeType,
243 final boolean isBase64Encoded) throws Exception {
244 getInstrumentation().runOnMainSync(new Runnable() {
247 mXWalkView.load(url, data);
252 protected void loadUrlSyncByContent(final XWalkView xWalkContent,
253 final TestHelperBridge contentsClient,
254 final String url) throws Exception {
255 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
256 int currentCallCount = pageFinishedHelper.getCallCount();
257 loadUrlAsyncByContent(xWalkContent, url);
259 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
263 protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
264 final String url) throws Exception {
265 getInstrumentation().runOnMainSync(new Runnable() {
268 xWalkContent.load(url, null);
273 protected String getTitleOnUiThread() throws Exception {
274 return runTestOnUiThreadAndGetResult(new Callable<String>() {
276 public String call() throws Exception {
277 return mXWalkView.getTitle();
282 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
284 FutureTask<R> task = new FutureTask<R>(callable);
285 getInstrumentation().waitForIdleSync();
286 getInstrumentation().runOnMainSync(task);
290 protected String getFileContent(String fileName) {
292 Context context = getInstrumentation().getContext();
293 InputStream inputStream = context.getAssets().open(fileName);
294 int size = inputStream.available();
295 byte buffer[] = new byte[size];
296 inputStream.read(buffer);
299 String fileContent = new String(buffer);
301 } catch (IOException e) {
302 throw new RuntimeException(e);
306 protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
307 return runTestOnUiThreadAndGetResult(new Callable<String>() {
309 public String call() throws Exception {
310 String title = xWalkContent.getTitle();
316 protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
317 final XWalkView xwalkContent) throws Exception {
318 return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
320 public XWalkSettings call() throws Exception {
321 return xwalkContent.getSettings();
326 protected XWalkView createXWalkViewContainerOnMainSync(
327 final Context context,
328 final XWalkClient client,
329 final XWalkResourceClient resourceClient,
330 final XWalkWebChromeClient webChromeClient) throws Exception {
331 final AtomicReference<XWalkView> xWalkViewContainer =
332 new AtomicReference<XWalkView>();
333 getInstrumentation().runOnMainSync(new Runnable() {
336 xWalkViewContainer.set(new XWalkView(context, getActivity()));
337 getActivity().addView(xWalkViewContainer.get());
338 xWalkViewContainer.get().setXWalkClient(client);
339 xWalkViewContainer.get().setResourceClient(resourceClient);
340 xWalkViewContainer.get().setXWalkWebChromeClient(webChromeClient);
344 return xWalkViewContainer.get();
347 protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
348 final TestHelperBridge helperBridge1,
349 final XWalkClient client0,
350 final XWalkClient client1,
351 final XWalkResourceClient resourceClient0,
352 final XWalkResourceClient resourceClient1,
353 final XWalkWebChromeClient chromeClient0,
354 final XWalkWebChromeClient chromeClient1,
355 final Context context) throws Throwable {
356 final XWalkView walkView0 = createXWalkViewContainerOnMainSync(context,
357 client0, resourceClient0, chromeClient0);
358 final XWalkView walkView1 = createXWalkViewContainerOnMainSync(context,
359 client1, resourceClient1, chromeClient1);
360 final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
362 getInstrumentation().runOnMainSync(new Runnable() {
365 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
369 return viewPair.get();
372 protected void loadAssetFile(String fileName) throws Exception {
373 String fileContent = getFileContent(fileName);
374 loadDataSync(fileName, fileContent, "text/html", false);
377 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
378 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
379 int currentCallCount = getTitleHelper.getCallCount();
380 String fileContent = getFileContent(fileName);
382 loadDataSync(fileName, fileContent, "text/html", false);
384 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
388 protected XWalkView getXWalkView() {
392 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
393 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
394 int currentCallCount = pageFinishedHelper.getCallCount();
396 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
400 protected void reloadSync(final int mode) throws Exception {
401 runTestWaitPageFinished(new Runnable(){
404 getInstrumentation().runOnMainSync(new Runnable() {
407 mXWalkView.reload(mode);
414 protected void goBackSync() throws Throwable {
415 runTestWaitPageFinished(new Runnable(){
418 getInstrumentation().runOnMainSync(new Runnable() {
421 mXWalkView.getNavigationHistory().navigate(
422 XWalkNavigationHistory.Direction.BACKWARD, 1);
429 protected void goForwardSync() throws Throwable {
430 runTestWaitPageFinished(new Runnable(){
433 getInstrumentation().runOnMainSync(new Runnable() {
436 mXWalkView.getNavigationHistory().navigate(
437 XWalkNavigationHistory.Direction.FORWARD, 1);
444 protected void clearHistoryOnUiThread() throws Exception {
445 getInstrumentation().runOnMainSync(new Runnable() {
448 mXWalkView.getNavigationHistory().clear();
453 protected boolean canGoBackOnUiThread() throws Throwable {
454 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
456 public Boolean call() {
457 return mXWalkView.getNavigationHistory().canGoBack();
462 protected boolean canGoForwardOnUiThread() throws Throwable {
463 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
465 public Boolean call() {
466 return mXWalkView.getNavigationHistory().canGoForward();
471 protected int historySizeOnUiThread() throws Throwable {
472 return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
474 public Integer call() {
475 return mXWalkView.getNavigationHistory().size();
480 protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
481 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
483 public Boolean call() {
484 return mXWalkView.getNavigationHistory().hasItemAt(index);
489 protected XWalkNavigationItem getItemAtOnUiThread(final int index) throws Throwable {
490 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
492 public XWalkNavigationItem call() {
493 return mXWalkView.getNavigationHistory().getItemAt(index);
498 protected XWalkNavigationItem getCurrentItemOnUiThread() throws Throwable {
499 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
501 public XWalkNavigationItem call() {
502 return mXWalkView.getNavigationHistory().getCurrentItem();
507 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
509 final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
510 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
511 getInstrumentation().runOnMainSync(new Runnable() {
514 helper.evaluateJavascript(mXWalkView, code);
517 helper.waitUntilHasValue();
518 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
519 return helper.getJsonResultAndClear();
522 protected ViewPair createViews() throws Throwable {
523 TestHelperBridge helperBridge0 = new TestHelperBridge();
524 TestHelperBridge helperBridge1 = new TestHelperBridge();
525 TestXWalkClientBase viewClient0 = new TestXWalkClientBase(helperBridge0);
526 TestXWalkClientBase viewClient1 = new TestXWalkClientBase(helperBridge1);
527 TestXWalkWebChromeClientBase chromeClient0 =
528 new TestXWalkWebChromeClientBase(helperBridge0);
529 TestXWalkWebChromeClientBase chromeClient1 =
530 new TestXWalkWebChromeClientBase(helperBridge1);
531 TestXWalkResourceClientBase resourceClient0 =
532 new TestXWalkResourceClientBase(helperBridge0);
533 TestXWalkResourceClientBase resourceClient1 =
534 new TestXWalkResourceClientBase(helperBridge1);
536 createViewsOnMainSync(helperBridge0, helperBridge1, viewClient0, viewClient1,
537 resourceClient0, resourceClient1, chromeClient0, chromeClient1,
543 protected String getUrlOnUiThread() throws Exception {
544 return runTestOnUiThreadAndGetResult(new Callable<String>() {
546 public String call() throws Exception {
547 return mXWalkView.getUrl();
552 protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
553 getInstrumentation().runOnMainSync(new Runnable() {
556 mXWalkView.clearCache(includeDiskFiles);
561 protected String getAPIVersionOnUiThread() throws Exception {
562 return runTestOnUiThreadAndGetResult(new Callable<String>() {
564 public String call() throws Exception {
565 return mXWalkView.getAPIVersion();
570 protected String getXWalkVersionOnUiThread() throws Exception {
571 return runTestOnUiThreadAndGetResult(new Callable<String>() {
573 public String call() throws Exception {
574 return mXWalkView.getXWalkVersion();