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;
34 public class XWalkViewTestBase
35 extends ActivityInstrumentationTestCase2<XWalkViewTestRunnerActivity> {
36 protected final static int WAIT_TIMEOUT_SECONDS = 15;
37 protected final static long WAIT_TIMEOUT_MS = 2000;
38 private final static int CHECK_INTERVAL = 100;
39 private final static String TAG = "XWalkViewTestBase";
40 private XWalkView mXWalkView;
41 final TestHelperBridge mTestHelperBridge = new TestHelperBridge();
43 class TestXWalkUIClientBase extends XWalkUIClient {
44 TestHelperBridge mInnerContentsClient;
45 public TestXWalkUIClientBase(TestHelperBridge client) {
46 super(getXWalkView());
47 mInnerContentsClient = client;
51 public void onPageLoadStarted(XWalkView view, String url) {
52 mInnerContentsClient.onPageStarted(url);
56 public void onPageLoadStopped(XWalkView view, String url, LoadStatus status) {
57 mInnerContentsClient.onPageFinished(url);
61 public void onReceivedTitle(XWalkView view, String title) {
62 mInnerContentsClient.onTitleChanged(title);
66 public void onJavascriptCloseWindow(XWalkView view) {
67 mInnerContentsClient.onJavascriptCloseWindow();
71 class TestXWalkUIClient extends TestXWalkUIClientBase {
72 public TestXWalkUIClient() {
73 super(mTestHelperBridge);
77 class TestXWalkResourceClientBase extends XWalkResourceClient {
78 TestHelperBridge mInnerContentsClient;
79 public TestXWalkResourceClientBase(TestHelperBridge client) {
81 mInnerContentsClient = client;
85 public void onLoadStarted(XWalkView view, String url) {
86 mInnerContentsClient.onLoadStarted(url);
90 public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
91 mInnerContentsClient.onReceivedLoadError(errorCode, description, failingUrl);
95 public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
97 return mInnerContentsClient.shouldInterceptLoadRequest(url);
101 public void onProgressChanged(XWalkView view, int progressInPercent) {
102 mTestHelperBridge.onProgressChanged(progressInPercent);
106 public boolean shouldOverrideUrlLoading(XWalkView view, String url) {
107 return mTestHelperBridge.shouldOverrideUrlLoading(url);
111 class TestXWalkResourceClient extends TestXWalkResourceClientBase {
112 public TestXWalkResourceClient() {
113 super(mTestHelperBridge);
117 void setUIClient(final XWalkUIClient client) {
118 getInstrumentation().runOnMainSync(new Runnable() {
121 getXWalkView().setUIClient(client);
126 void setResourceClient(final XWalkResourceClient client) {
127 getInstrumentation().runOnMainSync(new Runnable() {
130 getXWalkView().setResourceClient(client);
135 public XWalkViewTestBase() {
136 super(XWalkViewTestRunnerActivity.class);
140 protected void setUp() throws Exception {
143 // Must call getActivity() here but not in main thread.
144 final Activity activity = getActivity();
145 getInstrumentation().runOnMainSync(new Runnable() {
148 mXWalkView = new XWalkView(activity, activity);
149 getActivity().addView(mXWalkView);
150 mXWalkView.setUIClient(new TestXWalkUIClient());
151 mXWalkView.setResourceClient(new TestXWalkResourceClient());
152 // mXWalkView.getXWalkViewContentForTest().installWebContentsObserverForTest(mTestHelperBridge);
157 protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
158 return CriteriaHelper.pollForCriteria(new Criteria() {
160 public boolean isSatisfied() {
162 return runTestOnUiThreadAndGetResult(callable);
163 } catch (Throwable e) {
170 protected void loadJavaScriptUrl(final String url) throws Exception {
171 if (!url.startsWith("javascript:")) {
172 Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
178 protected void loadUrlSync(final String url) throws Exception {
179 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
180 int currentCallCount = pageFinishedHelper.getCallCount();
183 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
187 protected void loadUrlAsync(final String url) throws Exception {
188 getInstrumentation().runOnMainSync(new Runnable() {
191 mXWalkView.load(url, null);
196 protected void loadDataSync(final String url, final String data, final String mimeType,
197 final boolean isBase64Encoded) throws Exception {
198 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
199 int currentCallCount = pageFinishedHelper.getCallCount();
200 loadDataAsync(url, data, mimeType, isBase64Encoded);
201 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
205 protected void loadDataAsync(final String url, final String data, final String mimeType,
206 final boolean isBase64Encoded) throws Exception {
207 getInstrumentation().runOnMainSync(new Runnable() {
210 mXWalkView.load(url, data);
215 protected void loadUrlSyncByContent(final XWalkView xWalkContent,
216 final TestHelperBridge contentsClient,
217 final String url) throws Exception {
218 CallbackHelper pageFinishedHelper = contentsClient.getOnPageFinishedHelper();
219 int currentCallCount = pageFinishedHelper.getCallCount();
220 loadUrlAsyncByContent(xWalkContent, url);
222 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
226 protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
227 final String url) throws Exception {
228 getInstrumentation().runOnMainSync(new Runnable() {
231 xWalkContent.load(url, null);
236 protected String getTitleOnUiThread() throws Exception {
237 return runTestOnUiThreadAndGetResult(new Callable<String>() {
239 public String call() throws Exception {
240 return mXWalkView.getTitle();
245 protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
247 FutureTask<R> task = new FutureTask<R>(callable);
248 getInstrumentation().waitForIdleSync();
249 getInstrumentation().runOnMainSync(task);
253 protected String getFileContent(String fileName) {
255 Context context = getInstrumentation().getContext();
256 InputStream inputStream = context.getAssets().open(fileName);
257 int size = inputStream.available();
258 byte buffer[] = new byte[size];
259 inputStream.read(buffer);
262 String fileContent = new String(buffer);
264 } catch (IOException e) {
265 throw new RuntimeException(e);
269 protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
270 return runTestOnUiThreadAndGetResult(new Callable<String>() {
272 public String call() throws Exception {
273 String title = xWalkContent.getTitle();
279 protected XWalkView createXWalkViewContainerOnMainSync(
280 final Context context,
281 final XWalkUIClient uiClient,
282 final XWalkResourceClient resourceClient) throws Exception {
283 final AtomicReference<XWalkView> xWalkViewContainer =
284 new AtomicReference<XWalkView>();
285 getInstrumentation().runOnMainSync(new Runnable() {
288 xWalkViewContainer.set(new XWalkView(context, getActivity()));
289 getActivity().addView(xWalkViewContainer.get());
290 xWalkViewContainer.get().setUIClient(uiClient);
291 xWalkViewContainer.get().setResourceClient(resourceClient);
295 return xWalkViewContainer.get();
298 protected void loadAssetFile(String fileName) throws Exception {
299 String fileContent = getFileContent(fileName);
300 loadDataSync(fileName, fileContent, "text/html", false);
303 public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
304 CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
305 int currentCallCount = getTitleHelper.getCallCount();
306 String fileContent = getFileContent(fileName);
308 loadDataSync(fileName, fileContent, "text/html", false);
310 getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
314 protected XWalkView getXWalkView() {
318 protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
319 CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
320 int currentCallCount = pageFinishedHelper.getCallCount();
322 pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
326 protected void reloadSync(final int mode) throws Exception {
327 runTestWaitPageFinished(new Runnable(){
330 getInstrumentation().runOnMainSync(new Runnable() {
333 mXWalkView.reload(mode);
340 protected void goBackSync() throws Throwable {
341 runTestWaitPageFinished(new Runnable(){
344 getInstrumentation().runOnMainSync(new Runnable() {
347 mXWalkView.getNavigationHistory().navigate(
348 XWalkNavigationHistory.Direction.BACKWARD, 1);
355 protected void goForwardSync() throws Throwable {
356 runTestWaitPageFinished(new Runnable(){
359 getInstrumentation().runOnMainSync(new Runnable() {
362 mXWalkView.getNavigationHistory().navigate(
363 XWalkNavigationHistory.Direction.FORWARD, 1);
370 protected void clearHistoryOnUiThread() throws Exception {
371 getInstrumentation().runOnMainSync(new Runnable() {
374 mXWalkView.getNavigationHistory().clear();
379 protected boolean canGoBackOnUiThread() throws Throwable {
380 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
382 public Boolean call() {
383 return mXWalkView.getNavigationHistory().canGoBack();
388 protected boolean canGoForwardOnUiThread() throws Throwable {
389 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
391 public Boolean call() {
392 return mXWalkView.getNavigationHistory().canGoForward();
397 protected int historySizeOnUiThread() throws Throwable {
398 return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
400 public Integer call() {
401 return mXWalkView.getNavigationHistory().size();
406 protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
407 return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
409 public Boolean call() {
410 return mXWalkView.getNavigationHistory().hasItemAt(index);
415 protected XWalkNavigationItem getItemAtOnUiThread(final int index) throws Throwable {
416 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
418 public XWalkNavigationItem call() {
419 return mXWalkView.getNavigationHistory().getItemAt(index);
424 protected XWalkNavigationItem getCurrentItemOnUiThread() throws Throwable {
425 return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
427 public XWalkNavigationItem call() {
428 return mXWalkView.getNavigationHistory().getCurrentItem();
433 protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
435 final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
436 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
437 getInstrumentation().runOnMainSync(new Runnable() {
440 helper.evaluateJavascript(mXWalkView, code);
443 helper.waitUntilHasValue();
444 Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
445 return helper.getJsonResultAndClear();
448 protected String getUrlOnUiThread() throws Exception {
449 return runTestOnUiThreadAndGetResult(new Callable<String>() {
451 public String call() throws Exception {
452 return mXWalkView.getUrl();
457 protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
458 getInstrumentation().runOnMainSync(new Runnable() {
461 mXWalkView.clearCache(includeDiskFiles);
466 protected String getAPIVersionOnUiThread() throws Exception {
467 return runTestOnUiThreadAndGetResult(new Callable<String>() {
469 public String call() throws Exception {
470 return mXWalkView.getAPIVersion();
475 protected String getXWalkVersionOnUiThread() throws Exception {
476 return runTestOnUiThreadAndGetResult(new Callable<String>() {
478 public String call() throws Exception {
479 return mXWalkView.getXWalkVersion();
484 public void clickOnElementId(final String id) throws Exception {
485 Assert.assertTrue(CriteriaHelper.pollForCriteria(new Criteria() {
487 public boolean isSatisfied() {
489 String idIsNotNull = executeJavaScriptAndWaitForResult(
490 "document.getElementById('" + id + "') != null");
491 return idIsNotNull.equals("true");
492 } catch (Throwable t) {
494 Assert.fail("Failed to check if DOM is loaded: " + t.toString());
498 }, WAIT_TIMEOUT_MS, CHECK_INTERVAL));
501 String result = executeJavaScriptAndWaitForResult(
502 "var evObj = document.createEvent('Events'); " +
503 "evObj.initEvent('click', true, false); " +
504 "document.getElementById('" + id + "').dispatchEvent(evObj);" +
505 "console.log('element with id [" + id + "] clicked');");
506 } catch (Throwable t) {