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.XWalkResourceClient;
31 import org.xwalk.core.XWalkSettings;
32 import org.xwalk.core.XWalkView;
33 import org.xwalk.core.XWalkWebChromeClient;
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 TestXWalkClientBase extends XWalkClient {
43 TestHelperBridge mInnerContentsClient;
44 public TestXWalkClientBase(TestHelperBridge client) {
45 super(getXWalkView());
46 mInnerContentsClient = client;
50 public void onPageStarted(XWalkView view, String url) {
51 mInnerContentsClient.onPageStarted(url);
55 public void onPageFinished(XWalkView view, String url) {
56 mInnerContentsClient.onPageFinished(url);
60 class TestXWalkClient extends TestXWalkClientBase {
61 public TestXWalkClient() {
62 super(mTestHelperBridge);
66 class TestXWalkWebChromeClientBase extends XWalkWebChromeClient {
67 TestHelperBridge mInnerContentsClient;
68 public TestXWalkWebChromeClientBase(TestHelperBridge client) {
69 super(getXWalkView());
70 mInnerContentsClient = client;
74 public void onReceivedTitle(XWalkView view, String title) {
75 mInnerContentsClient.onTitleChanged(title);
79 class TestXWalkWebChromeClient extends TestXWalkWebChromeClientBase {
80 public TestXWalkWebChromeClient() {
81 super(mTestHelperBridge);
85 class TestXWalkResourceClientBase extends XWalkResourceClient {
86 TestHelperBridge mInnerContentsClient;
87 public TestXWalkResourceClientBase(TestHelperBridge client) {
89 mInnerContentsClient = client;
93 public void onLoadStarted(XWalkView view, String url) {
94 mTestHelperBridge.onLoadStarted(url);
98 public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
99 mTestHelperBridge.onReceivedLoadError(errorCode, description, failingUrl);
103 public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
105 return mTestHelperBridge.shouldInterceptLoadRequest(url);
109 class TestXWalkResourceClient extends TestXWalkResourceClientBase {
110 public TestXWalkResourceClient() {
111 super(mTestHelperBridge);
115 void setXWalkClient(final XWalkClient client) {
116 getInstrumentation().runOnMainSync(new Runnable() {
119 getXWalkView().setXWalkClient(client);
124 void setXWalkWebChromeClient(final XWalkWebChromeClient client) {
125 getInstrumentation().runOnMainSync(new Runnable() {
128 getXWalkView().setXWalkWebChromeClient(client);
133 void setResourceClient(final XWalkResourceClient client) {
134 getInstrumentation().runOnMainSync(new Runnable() {
137 getXWalkView().setResourceClient(client);
142 static class ViewPair {
143 private final XWalkView content0;
144 private final TestHelperBridge client0;
145 private final XWalkView content1;
146 private final TestHelperBridge client1;
148 ViewPair(XWalkView content0, TestHelperBridge client0,
149 XWalkView content1, TestHelperBridge client1) {
150 this.content0 = content0;
151 this.client0 = client0;
152 this.content1 = content1;
153 this.client1 = client1;
156 XWalkView getContent0() {
160 TestHelperBridge getClient0() {
164 XWalkView getContent1() {
168 TestHelperBridge getClient1() {
173 public XWalkViewTestBase() {
174 super(XWalkViewTestRunnerActivity.class);
178 protected void setUp() throws Exception {
181 // Must call getActivity() here but not in main thread.
182 final Activity activity = getActivity();
183 getInstrumentation().runOnMainSync(new Runnable() {
186 mXWalkView = new XWalkView(activity, activity);
187 getActivity().addView(mXWalkView);
188 // mXWalkView.getXWalkViewContentForTest().installWebContentsObserverForTest(mTestHelperBridge);
193 protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
194 return CriteriaHelper.pollForCriteria(new Criteria() {
196 public boolean isSatisfied() {
198 return runTestOnUiThreadAndGetResult(callable);
199 } catch (Throwable e) {
206 protected void loadJavaScriptUrl(final String url) throws Exception {
207 if (!url.startsWith("javascript:")) {
208 Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
214 protected void loadUrlSync(final String url) throws Exception {
215 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
216 int currentCallCount = pageFinishedHelper.getCallCount();
219 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
223 protected void loadUrlAsync(final String url) throws Exception {
224 getInstrumentation().runOnMainSync(new Runnable() {
227 mXWalkView.load(url, null);
232 protected void loadDataSync(final String url, final String data, final String mimeType,
233 final boolean isBase64Encoded) throws Exception {
234 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
235 int currentCallCount = pageFinishedHelper.getCallCount();
236 loadDataAsync(url, data, mimeType, isBase64Encoded);
237 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
241 protected void loadDataAsync(final String url, final String data, final String mimeType,
242 final boolean isBase64Encoded) throws Exception {
243 getInstrumentation().runOnMainSync(new Runnable() {
246 mXWalkView.load(url, data);
251 protected void loadUrlSyncByContent(final XWalkView xWalkContent,
252 final TestHelperBridge contentsClient,
253 final String url) throws Exception {
254 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
255 int currentCallCount = pageFinishedHelper.getCallCount();
256 loadUrlAsyncByContent(xWalkContent, url);
258 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
262 protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
263 final String url) throws Exception {
264 getInstrumentation().runOnMainSync(new Runnable() {
267 xWalkContent.load(url, null);
272 protected String getTitleOnUiThread() throws Exception {
273 return runTestOnUiThreadAndGetResult(new Callable<String>() {
275 public String call() throws Exception {
276 return mXWalkView.getTitle();
281 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
283 FutureTask<R> task = new FutureTask<R>(callable);
284 getInstrumentation().waitForIdleSync();
285 getInstrumentation().runOnMainSync(task);
289 protected String getFileContent(String fileName) {
291 Context context = getInstrumentation().getContext();
292 InputStream inputStream = context.getAssets().open(fileName);
293 int size = inputStream.available();
294 byte buffer[] = new byte[size];
295 inputStream.read(buffer);
298 String fileContent = new String(buffer);
300 } catch (IOException e) {
301 throw new RuntimeException(e);
305 protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
306 return runTestOnUiThreadAndGetResult(new Callable<String>() {
308 public String call() throws Exception {
309 String title = xWalkContent.getTitle();
315 protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
316 final XWalkView xwalkContent) throws Exception {
317 return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
319 public XWalkSettings call() throws Exception {
320 return xwalkContent.getSettings();
325 protected XWalkView createXWalkViewContainerOnMainSync(
326 final Context context,
327 final XWalkClient client,
328 final XWalkResourceClient resourceClient,
329 final XWalkWebChromeClient webChromeClient) throws Exception {
330 final AtomicReference<XWalkView> xWalkViewContainer =
331 new AtomicReference<XWalkView>();
332 getInstrumentation().runOnMainSync(new Runnable() {
335 xWalkViewContainer.set(new XWalkView(context, getActivity()));
336 getActivity().addView(xWalkViewContainer.get());
337 xWalkViewContainer.get().setXWalkClient(client);
338 xWalkViewContainer.get().setResourceClient(resourceClient);
339 xWalkViewContainer.get().setXWalkWebChromeClient(webChromeClient);
343 return xWalkViewContainer.get();
346 protected ViewPair createViewsOnMainSync(final TestHelperBridge helperBridge0,
347 final TestHelperBridge helperBridge1,
348 final XWalkClient client0,
349 final XWalkClient client1,
350 final XWalkResourceClient resourceClient0,
351 final XWalkResourceClient resourceClient1,
352 final XWalkWebChromeClient chromeClient0,
353 final XWalkWebChromeClient chromeClient1,
354 final Context context) throws Throwable {
355 final XWalkView walkView0 = createXWalkViewContainerOnMainSync(context,
356 client0, resourceClient0, chromeClient0);
357 final XWalkView walkView1 = createXWalkViewContainerOnMainSync(context,
358 client1, resourceClient1, chromeClient1);
359 final AtomicReference<ViewPair> viewPair = new AtomicReference<ViewPair>();
361 getInstrumentation().runOnMainSync(new Runnable() {
364 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
368 return viewPair.get();
371 protected void loadAssetFile(String fileName) throws Exception {
372 String fileContent = getFileContent(fileName);
373 loadDataSync(fileName, fileContent, "text/html", false);
376 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
377 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
378 int currentCallCount = getTitleHelper.getCallCount();
379 String fileContent = getFileContent(fileName);
381 loadDataSync(fileName, fileContent, "text/html", false);
383 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
387 protected XWalkView getXWalkView() {
391 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
392 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
393 int currentCallCount = pageFinishedHelper.getCallCount();
395 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
399 protected void reloadSync(final int mode) throws Exception {
400 runTestWaitPageFinished(new Runnable(){
403 getInstrumentation().runOnMainSync(new Runnable() {
406 mXWalkView.reload(mode);
413 protected void goBackSync() throws Throwable {
414 runTestWaitPageFinished(new Runnable(){
417 getInstrumentation().runOnMainSync(new Runnable() {
420 mXWalkView.getNavigationHistory().navigate(
421 XWalkNavigationHistory.Direction.BACKWARD, 1);
428 protected void goForwardSync() throws Throwable {
429 runTestWaitPageFinished(new Runnable(){
432 getInstrumentation().runOnMainSync(new Runnable() {
435 mXWalkView.getNavigationHistory().navigate(
436 XWalkNavigationHistory.Direction.FORWARD, 1);
443 protected void clearHistoryOnUiThread() throws Exception {
444 getInstrumentation().runOnMainSync(new Runnable() {
447 mXWalkView.getNavigationHistory().clear();
452 protected boolean canGoBackOnUiThread() throws Throwable {
453 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
455 public Boolean call() {
456 return mXWalkView.getNavigationHistory().canGoBack();
461 protected boolean canGoForwardOnUiThread() throws Throwable {
462 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
464 public Boolean call() {
465 return mXWalkView.getNavigationHistory().canGoForward();
470 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
472 final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
473 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
474 getInstrumentation().runOnMainSync(new Runnable() {
477 helper.evaluateJavascript(mXWalkView, code);
480 helper.waitUntilHasValue();
481 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
482 return helper.getJsonResultAndClear();
485 protected ViewPair createViews() throws Throwable {
486 TestHelperBridge helperBridge0 = new TestHelperBridge();
487 TestHelperBridge helperBridge1 = new TestHelperBridge();
488 TestXWalkClientBase viewClient0 = new TestXWalkClientBase(helperBridge0);
489 TestXWalkClientBase viewClient1 = new TestXWalkClientBase(helperBridge1);
490 TestXWalkWebChromeClientBase chromeClient0 =
491 new TestXWalkWebChromeClientBase(helperBridge0);
492 TestXWalkWebChromeClientBase chromeClient1 =
493 new TestXWalkWebChromeClientBase(helperBridge1);
494 TestXWalkResourceClientBase resourceClient0 =
495 new TestXWalkResourceClientBase(helperBridge0);
496 TestXWalkResourceClientBase resourceClient1 =
497 new TestXWalkResourceClientBase(helperBridge1);
499 createViewsOnMainSync(helperBridge0, helperBridge1, viewClient0, viewClient1,
500 resourceClient0, resourceClient1, chromeClient0, chromeClient1,
506 protected String getUrlOnUiThread() throws Exception {
507 return runTestOnUiThreadAndGetResult(new Callable<String>() {
509 public String call() throws Exception {
510 return mXWalkView.getUrl();
515 protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
516 getInstrumentation().runOnMainSync(new Runnable() {
519 mXWalkView.clearCache(includeDiskFiles);