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 public void onJavascriptCloseWindow(XWalkView view) {
66 mInnerContentsClient.onJavascriptCloseWindow();
70 class TestXWalkUIClient extends TestXWalkUIClientBase {
71 public TestXWalkUIClient() {
72 super(mTestHelperBridge);
76 class TestXWalkResourceClientBase extends XWalkResourceClient {
77 TestHelperBridge mInnerContentsClient;
78 public TestXWalkResourceClientBase(TestHelperBridge client) {
80 mInnerContentsClient = client;
84 public void onLoadStarted(XWalkView view, String url) {
85 mInnerContentsClient.onLoadStarted(url);
89 public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
90 mInnerContentsClient.onReceivedLoadError(errorCode, description, failingUrl);
94 public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
96 return mInnerContentsClient.shouldInterceptLoadRequest(url);
100 public void onProgressChanged(XWalkView view, int progressInPercent) {
101 mTestHelperBridge.onProgressChanged(progressInPercent);
105 class TestXWalkResourceClient extends TestXWalkResourceClientBase {
106 public TestXWalkResourceClient() {
107 super(mTestHelperBridge);
111 void setUIClient(final XWalkUIClient client) {
112 getInstrumentation().runOnMainSync(new Runnable() {
115 getXWalkView().setUIClient(client);
120 void setResourceClient(final XWalkResourceClient client) {
121 getInstrumentation().runOnMainSync(new Runnable() {
124 getXWalkView().setResourceClient(client);
129 static class ViewPair {
130 private final XWalkView content0;
131 private final TestHelperBridge client0;
132 private final XWalkView content1;
133 private final TestHelperBridge client1;
135 ViewPair(XWalkView content0, TestHelperBridge client0,
136 XWalkView content1, TestHelperBridge client1) {
137 this.content0 = content0;
138 this.client0 = client0;
139 this.content1 = content1;
140 this.client1 = client1;
143 XWalkView getContent0() {
147 TestHelperBridge getClient0() {
151 XWalkView getContent1() {
155 TestHelperBridge getClient1() {
160 public XWalkViewTestBase() {
161 super(XWalkViewTestRunnerActivity.class);
165 protected void setUp() throws Exception {
168 // Must call getActivity() here but not in main thread.
169 final Activity activity = getActivity();
170 getInstrumentation().runOnMainSync(new Runnable() {
173 mXWalkView = new XWalkView(activity, activity);
174 getActivity().addView(mXWalkView);
175 mXWalkView.setUIClient(new TestXWalkUIClient());
176 mXWalkView.setResourceClient(new TestXWalkResourceClient());
177 // mXWalkView.getXWalkViewContentForTest().installWebContentsObserverForTest(mTestHelperBridge);
182 protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
183 return CriteriaHelper.pollForCriteria(new Criteria() {
185 public boolean isSatisfied() {
187 return runTestOnUiThreadAndGetResult(callable);
188 } catch (Throwable e) {
195 protected void loadJavaScriptUrl(final String url) throws Exception {
196 if (!url.startsWith("javascript:")) {
197 Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
203 protected void loadUrlSync(final String url) throws Exception {
204 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
205 int currentCallCount = pageFinishedHelper.getCallCount();
208 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
212 protected void loadUrlAsync(final String url) throws Exception {
213 getInstrumentation().runOnMainSync(new Runnable() {
216 mXWalkView.load(url, null);
221 protected void loadDataSync(final String url, final String data, final String mimeType,
222 final boolean isBase64Encoded) throws Exception {
223 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
224 int currentCallCount = pageFinishedHelper.getCallCount();
225 loadDataAsync(url, data, mimeType, isBase64Encoded);
226 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
230 protected void loadDataAsync(final String url, final String data, final String mimeType,
231 final boolean isBase64Encoded) throws Exception {
232 getInstrumentation().runOnMainSync(new Runnable() {
235 mXWalkView.load(url, data);
240 protected void loadUrlSyncByContent(final XWalkView xWalkContent,
241 final TestHelperBridge contentsClient,
242 final String url) throws Exception {
243 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
244 int currentCallCount = pageFinishedHelper.getCallCount();
245 loadUrlAsyncByContent(xWalkContent, url);
247 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
251 protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
252 final String url) throws Exception {
253 getInstrumentation().runOnMainSync(new Runnable() {
256 xWalkContent.load(url, null);
261 protected String getTitleOnUiThread() throws Exception {
262 return runTestOnUiThreadAndGetResult(new Callable<String>() {
264 public String call() throws Exception {
265 return mXWalkView.getTitle();
270 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
272 FutureTask<R> task = new FutureTask<R>(callable);
273 getInstrumentation().waitForIdleSync();
274 getInstrumentation().runOnMainSync(task);
278 protected String getFileContent(String fileName) {
280 Context context = getInstrumentation().getContext();
281 InputStream inputStream = context.getAssets().open(fileName);
282 int size = inputStream.available();
283 byte buffer[] = new byte[size];
284 inputStream.read(buffer);
287 String fileContent = new String(buffer);
289 } catch (IOException e) {
290 throw new RuntimeException(e);
294 protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
295 return runTestOnUiThreadAndGetResult(new Callable<String>() {
297 public String call() throws Exception {
298 String title = xWalkContent.getTitle();
304 protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
305 final XWalkView xwalkContent) throws Exception {
306 return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
308 public XWalkSettings call() throws Exception {
309 return xwalkContent.getSettings();
314 protected XWalkView createXWalkViewContainerOnMainSync(
315 final Context context,
316 final XWalkUIClient uiClient,
317 final XWalkResourceClient resourceClient) throws Exception {
318 final AtomicReference<XWalkView> xWalkViewContainer =
319 new AtomicReference<XWalkView>();
320 getInstrumentation().runOnMainSync(new Runnable() {
323 xWalkViewContainer.set(new XWalkView(context, getActivity()));
324 getActivity().addView(xWalkViewContainer.get());
325 xWalkViewContainer.get().setUIClient(uiClient);
326 xWalkViewContainer.get().setResourceClient(resourceClient);
330 return xWalkViewContainer.get();
333 protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
334 final TestHelperBridge helperBridge1,
335 final XWalkUIClient uiClient0,
336 final XWalkUIClient uiClient1,
337 final XWalkResourceClient resourceClient0,
338 final XWalkResourceClient resourceClient1,
339 final Context context) throws Throwable {
340 final XWalkView walkView0 = createXWalkViewContainerOnMainSync(context,
341 uiClient0, resourceClient0);
342 final XWalkView walkView1 = createXWalkViewContainerOnMainSync(context,
343 uiClient1, resourceClient1);
344 final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
346 getInstrumentation().runOnMainSync(new Runnable() {
349 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
353 return viewPair.get();
356 protected void loadAssetFile(String fileName) throws Exception {
357 String fileContent = getFileContent(fileName);
358 loadDataSync(fileName, fileContent, "text/html", false);
361 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
362 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
363 int currentCallCount = getTitleHelper.getCallCount();
364 String fileContent = getFileContent(fileName);
366 loadDataSync(fileName, fileContent, "text/html", false);
368 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
372 protected XWalkView getXWalkView() {
376 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
377 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
378 int currentCallCount = pageFinishedHelper.getCallCount();
380 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
384 protected void reloadSync(final int mode) throws Exception {
385 runTestWaitPageFinished(new Runnable(){
388 getInstrumentation().runOnMainSync(new Runnable() {
391 mXWalkView.reload(mode);
398 protected void goBackSync() throws Throwable {
399 runTestWaitPageFinished(new Runnable(){
402 getInstrumentation().runOnMainSync(new Runnable() {
405 mXWalkView.getNavigationHistory().navigate(
406 XWalkNavigationHistory.Direction.BACKWARD, 1);
413 protected void goForwardSync() throws Throwable {
414 runTestWaitPageFinished(new Runnable(){
417 getInstrumentation().runOnMainSync(new Runnable() {
420 mXWalkView.getNavigationHistory().navigate(
421 XWalkNavigationHistory.Direction.FORWARD, 1);
428 protected void clearHistoryOnUiThread() throws Exception {
429 getInstrumentation().runOnMainSync(new Runnable() {
432 mXWalkView.getNavigationHistory().clear();
437 protected boolean canGoBackOnUiThread() throws Throwable {
438 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
440 public Boolean call() {
441 return mXWalkView.getNavigationHistory().canGoBack();
446 protected boolean canGoForwardOnUiThread() throws Throwable {
447 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
449 public Boolean call() {
450 return mXWalkView.getNavigationHistory().canGoForward();
455 protected int historySizeOnUiThread() throws Throwable {
456 return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
458 public Integer call() {
459 return mXWalkView.getNavigationHistory().size();
464 protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
465 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
467 public Boolean call() {
468 return mXWalkView.getNavigationHistory().hasItemAt(index);
473 protected XWalkNavigationItem getItemAtOnUiThread(final int index) throws Throwable {
474 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
476 public XWalkNavigationItem call() {
477 return mXWalkView.getNavigationHistory().getItemAt(index);
482 protected XWalkNavigationItem getCurrentItemOnUiThread() throws Throwable {
483 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
485 public XWalkNavigationItem call() {
486 return mXWalkView.getNavigationHistory().getCurrentItem();
491 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
493 final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
494 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
495 getInstrumentation().runOnMainSync(new Runnable() {
498 helper.evaluateJavascript(mXWalkView, code);
501 helper.waitUntilHasValue();
502 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
503 return helper.getJsonResultAndClear();
506 protected ViewPair createViews() throws Throwable {
507 TestHelperBridge helperBridge0 = new TestHelperBridge();
508 TestHelperBridge helperBridge1 = new TestHelperBridge();
509 TestXWalkUIClientBase uiClient0 = new TestXWalkUIClientBase(helperBridge0);
510 TestXWalkUIClientBase uiClient1 = new TestXWalkUIClientBase(helperBridge1);
511 TestXWalkResourceClientBase resourceClient0 =
512 new TestXWalkResourceClientBase(helperBridge0);
513 TestXWalkResourceClientBase resourceClient1 =
514 new TestXWalkResourceClientBase(helperBridge1);
516 createViewsOnMainSync(helperBridge0, helperBridge1, uiClient0, uiClient1,
517 resourceClient0, resourceClient1, getActivity());
522 protected String getUrlOnUiThread() throws Exception {
523 return runTestOnUiThreadAndGetResult(new Callable<String>() {
525 public String call() throws Exception {
526 return mXWalkView.getUrl();
531 protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
532 getInstrumentation().runOnMainSync(new Runnable() {
535 mXWalkView.clearCache(includeDiskFiles);
540 protected String getAPIVersionOnUiThread() throws Exception {
541 return runTestOnUiThreadAndGetResult(new Callable<String>() {
543 public String call() throws Exception {
544 return mXWalkView.getAPIVersion();
549 protected String getXWalkVersionOnUiThread() throws Exception {
550 return runTestOnUiThreadAndGetResult(new Callable<String>() {
552 public String call() throws Exception {
553 return mXWalkView.getXWalkVersion();