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;
27 import org.chromium.content.browser.test.util.TestCallbackHelperContainer.OnEvaluateJavaScriptResultHelper;
28 import org.xwalk.core.XWalkClient;
29 import org.xwalk.core.XWalkContent;
30 import org.xwalk.core.XWalkContentsClient;
31 import org.xwalk.core.XWalkNavigationHistory;
32 import org.xwalk.core.XWalkResourceClient;
33 import org.xwalk.core.XWalkResourceClientImpl;
34 import org.xwalk.core.XWalkSettings;
35 import org.xwalk.core.XWalkView;
36 import org.xwalk.core.XWalkWebChromeClient;
38 public class XWalkViewTestBase
39 extends ActivityInstrumentationTestCase2<XWalkViewTestRunnerActivity> {
40 protected final static int WAIT_TIMEOUT_SECONDS = 15;
41 private final static String TAG = "XWalkViewTestBase";
42 private XWalkView mXWalkView;
43 final TestHelperBridge mTestHelperBridge = new TestHelperBridge();
45 class TestXWalkClientBase extends XWalkClient {
46 TestHelperBridge mInnerContentsClient;
47 public TestXWalkClientBase(TestHelperBridge client) {
48 super(getXWalkView().getContext(), getXWalkView());
49 mInnerContentsClient = client;
53 public void onPageStarted(XWalkView view, String url) {
54 mInnerContentsClient.onPageStarted(url);
58 public void onPageFinished(XWalkView view, String url) {
59 mInnerContentsClient.onPageFinished(url);
63 class TestXWalkClient extends TestXWalkClientBase {
64 public TestXWalkClient() {
65 super(mTestHelperBridge);
69 class TestXWalkWebChromeClientBase extends XWalkWebChromeClient {
70 TestHelperBridge mInnerContentsClient;
71 public TestXWalkWebChromeClientBase(TestHelperBridge client) {
72 super(getXWalkView().getContext(), getXWalkView());
73 mInnerContentsClient = client;
77 public void onReceivedTitle(XWalkView view, String title) {
78 mInnerContentsClient.onTitleChanged(title);
82 class TestXWalkWebChromeClient extends TestXWalkWebChromeClientBase {
83 public TestXWalkWebChromeClient() {
84 super(mTestHelperBridge);
88 class TestXWalkResourceClientBase extends XWalkResourceClient {
89 TestHelperBridge mInnerContentsClient;
90 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 XWalkContent content0;
146 private final TestHelperBridge client0;
147 private final XWalkContent content1;
148 private final TestHelperBridge client1;
150 ViewPair(XWalkContent content0, TestHelperBridge client0,
151 XWalkContent content1, TestHelperBridge client1) {
152 this.content0 = content0;
153 this.client0 = client0;
154 this.content1 = content1;
155 this.client1 = client1;
158 XWalkContent getContent0() {
162 TestHelperBridge getClient0() {
166 XWalkContent 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 data, final String mimeType,
235 final boolean isBase64Encoded) throws Exception {
236 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
237 int currentCallCount = pageFinishedHelper.getCallCount();
238 loadDataAsync(data, mimeType, isBase64Encoded);
239 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
243 protected void loadDataAsync(final String data, final String mimeType,
244 final boolean isBase64Encoded) throws Exception {
245 getInstrumentation().runOnMainSync(new Runnable() {
248 mXWalkView.getXWalkViewContentForTest().getContentViewCoreForTest(
249 ).loadUrl(LoadUrlParams.createLoadDataParams(
250 data, mimeType, isBase64Encoded));
255 protected void loadUrlSyncByContent(final XWalkContent xWalkContent,
256 final TestHelperBridge contentsClient,
257 final String url) throws Exception {
258 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
259 int currentCallCount = pageFinishedHelper.getCallCount();
260 loadUrlAsyncByContent(xWalkContent, url);
262 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
266 protected void loadUrlAsyncByContent(final XWalkContent xWalkContent,
267 final String url) throws Exception {
268 getInstrumentation().runOnMainSync(new Runnable() {
271 xWalkContent.loadUrl(url);
276 protected String getTitleOnUiThread() throws Exception {
277 return runTestOnUiThreadAndGetResult(new Callable<String>() {
279 public String call() throws Exception {
280 return mXWalkView.getTitle();
285 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
287 FutureTask<R> task = new FutureTask<R>(callable);
288 getInstrumentation().waitForIdleSync();
289 getInstrumentation().runOnMainSync(task);
293 protected String getFileContent(String fileName) {
295 Context context = getInstrumentation().getContext();
296 InputStream inputStream = context.getAssets().open(fileName);
297 int size = inputStream.available();
298 byte buffer[] = new byte[size];
299 inputStream.read(buffer);
302 String fileContent = new String(buffer);
304 } catch (IOException e) {
305 throw new RuntimeException(e);
309 protected String getTitleOnUiThreadByContent(final XWalkContent xWalkContent) throws Exception {
310 return runTestOnUiThreadAndGetResult(new Callable<String>() {
312 public String call() throws Exception {
313 String title = xWalkContent.getContentViewCoreForTest().getTitle();
319 protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
320 final XWalkContent xwalkContent) throws Exception {
321 return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
323 public XWalkSettings call() throws Exception {
324 return xwalkContent.getSettings();
329 protected XWalkView createXWalkViewContainerOnMainSync(
330 final Context context,
331 final XWalkClient client,
332 final XWalkResourceClient resourceClient,
333 final XWalkWebChromeClient webChromeClient) throws Exception {
334 final AtomicReference<XWalkView> xWalkViewContainer =
335 new AtomicReference<XWalkView>();
336 getInstrumentation().runOnMainSync(new Runnable() {
339 xWalkViewContainer.set(new XWalkView(context, getActivity()));
340 getActivity().addView(xWalkViewContainer.get());
341 xWalkViewContainer.get().setXWalkClient(client);
342 xWalkViewContainer.get().setResourceClient(resourceClient);
343 xWalkViewContainer.get().setXWalkWebChromeClient(webChromeClient);
347 return xWalkViewContainer.get();
350 protected XWalkContent getXWalkContentOnMainSync(final XWalkView view) throws Exception {
351 final AtomicReference<XWalkContent> xWalkContent =
352 new AtomicReference<XWalkContent>();
353 getInstrumentation().runOnMainSync(new Runnable() {
356 xWalkContent.set(view.getXWalkViewContentForTest());
360 return xWalkContent.get();
363 protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
364 final TestHelperBridge helperBridge1,
365 final XWalkClient client0,
366 final XWalkClient client1,
367 final XWalkResourceClient resourceClient0,
368 final XWalkResourceClient resourceClient1,
369 final XWalkWebChromeClient chromeClient0,
370 final XWalkWebChromeClient chromeClient1,
371 final Context context) throws Throwable {
372 final XWalkView walkView0 = createXWalkViewContainerOnMainSync(context,
373 client0, resourceClient0, chromeClient0);
374 final XWalkView walkView1 = createXWalkViewContainerOnMainSync(context,
375 client1, resourceClient1, chromeClient1);
376 final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
378 getInstrumentation().runOnMainSync(new Runnable() {
381 XWalkContent content0 = walkView0.getXWalkViewContentForTest();
382 XWalkContent content1 = walkView1.getXWalkViewContentForTest();
383 viewPair.set(new ViewPair(content0, helperBridge0, content1, helperBridge1));
387 return viewPair.get();
390 protected void loadAssetFile(String fileName) throws Exception {
391 String fileContent = getFileContent(fileName);
392 loadDataSync(fileContent, "text/html", false);
395 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
396 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
397 int currentCallCount = getTitleHelper.getCallCount();
398 String fileContent = getFileContent(fileName);
400 loadDataSync(fileContent, "text/html", false);
402 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
406 protected XWalkView getXWalkView() {
410 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
411 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
412 int currentCallCount = pageFinishedHelper.getCallCount();
414 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
418 protected void reloadSync() throws Exception {
419 runTestWaitPageFinished(new Runnable(){
422 getInstrumentation().runOnMainSync(new Runnable() {
432 protected void goBackSync() throws Throwable {
433 runTestWaitPageFinished(new Runnable(){
436 getInstrumentation().runOnMainSync(new Runnable() {
439 mXWalkView.getNavigationHistory().navigate(
440 XWalkNavigationHistory.Direction.BACKWARD, 1);
447 protected void goForwardSync() throws Throwable {
448 runTestWaitPageFinished(new Runnable(){
451 getInstrumentation().runOnMainSync(new Runnable() {
454 mXWalkView.getNavigationHistory().navigate(
455 XWalkNavigationHistory.Direction.FORWARD, 1);
462 protected void clearHistoryOnUiThread() throws Exception {
463 getInstrumentation().runOnMainSync(new Runnable() {
466 mXWalkView.getNavigationHistory().clear();
471 protected boolean canGoBackOnUiThread() throws Throwable {
472 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
474 public Boolean call() {
475 return mXWalkView.getNavigationHistory().canGoBack();
480 protected boolean canGoForwardOnUiThread() throws Throwable {
481 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
483 public Boolean call() {
484 return mXWalkView.getNavigationHistory().canGoForward();
489 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
490 final OnEvaluateJavaScriptResultHelper helper =
491 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
492 getInstrumentation().runOnMainSync(new Runnable() {
495 XWalkContent content = mXWalkView.getXWalkViewContentForTest();
496 helper.evaluateJavaScript(content.getContentViewCoreForTest(), code);
499 helper.waitUntilHasValue();
500 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
501 return helper.getJsonResultAndClear();
504 protected ViewPair createViews() throws Throwable {
505 TestHelperBridge helperBridge0 = new TestHelperBridge();
506 TestHelperBridge helperBridge1 = new TestHelperBridge();
507 TestXWalkClientBase viewClient0 = new TestXWalkClientBase(helperBridge0);
508 TestXWalkClientBase viewClient1 = new TestXWalkClientBase(helperBridge1);
509 TestXWalkWebChromeClientBase chromeClient0 =
510 new TestXWalkWebChromeClientBase(helperBridge0);
511 TestXWalkWebChromeClientBase chromeClient1 =
512 new TestXWalkWebChromeClientBase(helperBridge1);
513 TestXWalkResourceClientBase resourceClient0 =
514 new TestXWalkResourceClientBase(helperBridge0);
515 TestXWalkResourceClientBase resourceClient1 =
516 new TestXWalkResourceClientBase(helperBridge1);
518 createViewsOnMainSync(helperBridge0, helperBridge1, viewClient0, viewClient1,
519 resourceClient0, resourceClient1, chromeClient0, chromeClient1,