8be4a33b7fd216a6472810214c8013ecb474bc2a
[platform/framework/web/crosswalk.git] / src / xwalk / test / android / core / javatests / src / org / xwalk / core / xwview / test / XWalkViewTestBase.java
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.
5
6 package org.xwalk.core.xwview.test;
7
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;
13
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;
20
21 import junit.framework.Assert;
22
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
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;
34
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();
41
42     class TestXWalkUIClientBase extends XWalkUIClient {
43         TestHelperBridge mInnerContentsClient;
44         public TestXWalkUIClientBase(TestHelperBridge client) {
45             super(getXWalkView());
46             mInnerContentsClient = client;
47         }
48
49         @Override
50         public void onPageLoadStarted(XWalkView view, String url) {
51             mInnerContentsClient.onPageStarted(url);
52         }
53
54         @Override
55         public void onPageLoadStopped(XWalkView view, String url, LoadStatus status) {
56             mInnerContentsClient.onPageFinished(url);
57         }
58
59         @Override
60         public void onReceivedTitle(XWalkView view, String title) {
61             mInnerContentsClient.onTitleChanged(title);
62         }
63
64         @Override
65         public void onJavascriptCloseWindow(XWalkView view) {
66             mInnerContentsClient.onJavascriptCloseWindow();
67         }
68     }
69
70     class TestXWalkUIClient extends TestXWalkUIClientBase {
71         public TestXWalkUIClient() {
72             super(mTestHelperBridge);
73         }
74     }
75
76     class TestXWalkResourceClientBase extends XWalkResourceClient {
77         TestHelperBridge mInnerContentsClient;
78         public TestXWalkResourceClientBase(TestHelperBridge client) {
79             super(mXWalkView);
80             mInnerContentsClient = client;
81         }
82
83         @Override
84         public void onLoadStarted(XWalkView view, String url) {
85             mInnerContentsClient.onLoadStarted(url);
86         }
87
88         @Override
89         public void onReceivedLoadError(XWalkView view, int errorCode, String description, String failingUrl) {
90             mInnerContentsClient.onReceivedLoadError(errorCode, description, failingUrl);
91         }
92
93         @Override
94         public WebResourceResponse shouldInterceptLoadRequest(XWalkView view,
95                 String url) {
96             return mInnerContentsClient.shouldInterceptLoadRequest(url);
97         }
98
99         @Override
100         public void onProgressChanged(XWalkView view, int progressInPercent) {
101             mTestHelperBridge.onProgressChanged(progressInPercent);
102         }
103     }
104
105     class TestXWalkResourceClient extends TestXWalkResourceClientBase {
106         public TestXWalkResourceClient() {
107             super(mTestHelperBridge);
108         }
109     }
110
111     void setUIClient(final XWalkUIClient client) {
112         getInstrumentation().runOnMainSync(new Runnable() {
113             @Override
114             public void run() {
115                 getXWalkView().setUIClient(client);
116             }
117         });
118     }
119
120     void setResourceClient(final XWalkResourceClient client) {
121         getInstrumentation().runOnMainSync(new Runnable() {
122             @Override
123             public void run() {
124                 getXWalkView().setResourceClient(client);
125             }
126         });
127     }
128
129     static class ViewPair {
130         private final XWalkView content0;
131         private final TestHelperBridge client0;
132         private final XWalkView content1;
133         private final TestHelperBridge client1;
134
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;
141         }
142
143         XWalkView getContent0() {
144             return content0;
145         }
146
147         TestHelperBridge getClient0() {
148             return client0;
149         }
150
151         XWalkView getContent1() {
152             return content1;
153         }
154
155         TestHelperBridge getClient1() {
156             return client1;
157         }
158     }
159
160     public XWalkViewTestBase() {
161         super(XWalkViewTestRunnerActivity.class);
162     }
163
164     @Override
165     protected void setUp() throws Exception {
166         super.setUp();
167
168         // Must call getActivity() here but not in main thread.
169         final Activity activity = getActivity();
170         getInstrumentation().runOnMainSync(new Runnable() {
171             @Override
172             public void run() {
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);
178             }
179         });
180     }
181
182     protected boolean pollOnUiThread(final Callable<Boolean> callable) throws Exception {
183         return CriteriaHelper.pollForCriteria(new Criteria() {
184             @Override
185             public boolean isSatisfied() {
186                 try {
187                     return runTestOnUiThreadAndGetResult(callable);
188                 } catch (Throwable e) {
189                     return false;
190                 }
191             }
192         });
193     }
194
195     protected void loadJavaScriptUrl(final String url) throws Exception {
196         if (!url.startsWith("javascript:")) {
197             Log.w(TAG, "loadJavascriptUrl only accepts javascript: url");
198             return;
199         }
200         loadUrlAsync(url);
201     }
202
203     protected void loadUrlSync(final String url) throws Exception {
204         CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
205         int currentCallCount = pageFinishedHelper.getCallCount();
206         loadUrlAsync(url);
207
208         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
209                 TimeUnit.SECONDS);
210     }
211
212     protected void loadUrlAsync(final String url) throws Exception {
213         getInstrumentation().runOnMainSync(new Runnable() {
214             @Override
215             public void run() {
216                 mXWalkView.load(url, null);
217             }
218         });
219     }
220
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,
227                 TimeUnit.SECONDS);
228     }
229
230     protected void loadDataAsync(final String url, final String data, final String mimeType,
231              final boolean isBase64Encoded) throws Exception {
232         getInstrumentation().runOnMainSync(new Runnable() {
233             @Override
234             public void run() {
235                 mXWalkView.load(url, data);
236             }
237         });
238     }
239
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);
246
247         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
248                 TimeUnit.SECONDS);
249     }
250
251     protected void loadUrlAsyncByContent(final XWalkView xWalkContent,
252             final String url) throws Exception {
253         getInstrumentation().runOnMainSync(new Runnable() {
254             @Override
255             public void run() {
256                 xWalkContent.load(url, null);
257             }
258         });
259     }
260
261     protected String getTitleOnUiThread() throws Exception {
262         return runTestOnUiThreadAndGetResult(new Callable<String>() {
263             @Override
264             public String call() throws Exception {
265                 return mXWalkView.getTitle();
266             }
267         });
268     }
269
270     protected <R> R runTestOnUiThreadAndGetResult(Callable<R> callable)
271             throws Exception {
272         FutureTask<R> task = new FutureTask<R>(callable);
273         getInstrumentation().waitForIdleSync();
274         getInstrumentation().runOnMainSync(task);
275         return task.get();
276     }
277
278     protected String getFileContent(String fileName) {
279         try {
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);
285             inputStream.close();
286
287             String fileContent = new String(buffer);
288             return fileContent;
289         } catch (IOException e) {
290             throw new RuntimeException(e);
291         }
292     }
293
294     protected String getTitleOnUiThreadByContent(final XWalkView xWalkContent) throws Exception {
295         return runTestOnUiThreadAndGetResult(new Callable<String>() {
296             @Override
297             public String call() throws Exception {
298                 String title = xWalkContent.getTitle();
299                 return title;
300             }
301         });
302     }
303
304     protected XWalkSettings getXWalkSettingsOnUiThreadByContent(
305             final XWalkView xwalkContent) throws Exception {
306         return runTestOnUiThreadAndGetResult(new Callable<XWalkSettings>() {
307             @Override
308             public XWalkSettings call() throws Exception {
309                 return xwalkContent.getSettings();
310             }
311         });
312     }
313
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() {
321             @Override
322             public void run() {
323                 xWalkViewContainer.set(new XWalkView(context, getActivity()));
324                 getActivity().addView(xWalkViewContainer.get());
325                 xWalkViewContainer.get().setUIClient(uiClient);
326                 xWalkViewContainer.get().setResourceClient(resourceClient);
327             }
328         });
329
330         return xWalkViewContainer.get();
331     }
332
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>();
345
346         getInstrumentation().runOnMainSync(new Runnable() {
347             @Override
348             public void run() {
349                 viewPair.set(new ViewPair(walkView0, helperBridge0, walkView1, helperBridge1));
350             }
351         });
352
353         return viewPair.get();
354     }
355
356     protected void loadAssetFile(String fileName) throws Exception {
357         String fileContent = getFileContent(fileName);
358         loadDataSync(fileName, fileContent, "text/html", false);
359     }
360
361     public void loadAssetFileAndWaitForTitle(String fileName) throws Exception {
362         CallbackHelper getTitleHelper = mTestHelperBridge.getOnTitleUpdatedHelper();
363         int currentCallCount = getTitleHelper.getCallCount();
364         String fileContent = getFileContent(fileName);
365
366         loadDataSync(fileName, fileContent, "text/html", false);
367
368         getTitleHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
369                 TimeUnit.SECONDS);
370     }
371
372     protected XWalkView getXWalkView() {
373         return mXWalkView;
374     }
375
376     protected void runTestWaitPageFinished(Runnable runnable) throws Exception{
377         CallbackHelper pageFinishedHelper = mTestHelperBridge.getOnPageFinishedHelper();
378         int currentCallCount = pageFinishedHelper.getCallCount();
379         runnable.run();
380         pageFinishedHelper.waitForCallback(currentCallCount, 1, WAIT_TIMEOUT_SECONDS,
381                 TimeUnit.SECONDS);
382     }
383
384     protected void reloadSync(final int mode) throws Exception {
385         runTestWaitPageFinished(new Runnable(){
386             @Override
387             public void run() {
388                 getInstrumentation().runOnMainSync(new Runnable() {
389                     @Override
390                     public void run() {
391                         mXWalkView.reload(mode);
392                     }
393                 });
394             }
395         });
396     }
397
398     protected void goBackSync() throws Throwable {
399         runTestWaitPageFinished(new Runnable(){
400             @Override
401             public void run() {
402                 getInstrumentation().runOnMainSync(new Runnable() {
403                     @Override
404                     public void run() {
405                         mXWalkView.getNavigationHistory().navigate(
406                             XWalkNavigationHistory.Direction.BACKWARD, 1);
407                     }
408                 });
409             }
410         });
411     }
412
413     protected void goForwardSync() throws Throwable {
414         runTestWaitPageFinished(new Runnable(){
415             @Override
416             public void run() {
417                 getInstrumentation().runOnMainSync(new Runnable() {
418                     @Override
419                     public void run() {
420                         mXWalkView.getNavigationHistory().navigate(
421                             XWalkNavigationHistory.Direction.FORWARD, 1);
422                     }
423                 });
424             }
425         });
426     }
427
428     protected void clearHistoryOnUiThread() throws Exception {
429         getInstrumentation().runOnMainSync(new Runnable() {
430             @Override
431             public void run() {
432                 mXWalkView.getNavigationHistory().clear();
433             }
434         });
435     }
436
437     protected boolean canGoBackOnUiThread() throws Throwable {
438         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
439             @Override
440             public Boolean call() {
441                 return mXWalkView.getNavigationHistory().canGoBack();
442             }
443         });
444     }
445
446     protected boolean canGoForwardOnUiThread() throws Throwable {
447         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
448             @Override
449             public Boolean call() {
450                 return mXWalkView.getNavigationHistory().canGoForward();
451             }
452         });
453     }
454
455     protected int historySizeOnUiThread() throws Throwable {
456         return runTestOnUiThreadAndGetResult(new Callable<Integer>() {
457             @Override
458             public Integer call() {
459                 return mXWalkView.getNavigationHistory().size();
460             }
461         });
462     }
463
464     protected boolean hasItemAtOnUiThread(final int index) throws Throwable {
465         return runTestOnUiThreadAndGetResult(new Callable<Boolean>() {
466             @Override
467             public Boolean call() {
468                 return mXWalkView.getNavigationHistory().hasItemAt(index);
469             }
470         });
471     }
472
473     protected XWalkNavigationItem getItemAtOnUiThread(final int index) throws Throwable {
474         return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
475             @Override
476             public XWalkNavigationItem call() {
477                 return mXWalkView.getNavigationHistory().getItemAt(index);
478             }
479         });
480     }
481
482     protected XWalkNavigationItem getCurrentItemOnUiThread() throws Throwable {
483         return runTestOnUiThreadAndGetResult(new Callable<XWalkNavigationItem>() {
484             @Override
485             public XWalkNavigationItem call() {
486                 return mXWalkView.getNavigationHistory().getCurrentItem();
487             }
488         });
489     }
490
491     protected String executeJavaScriptAndWaitForResult(final String code) throws Exception {
492
493         final TestHelperBridge.OnEvaluateJavaScriptResultHelper helper =
494                 mTestHelperBridge.getOnEvaluateJavaScriptResultHelper();
495         getInstrumentation().runOnMainSync(new Runnable() {
496             @Override
497             public void run() {
498                 helper.evaluateJavascript(mXWalkView, code);
499             }
500         });
501         helper.waitUntilHasValue();
502         Assert.assertTrue("Failed to retrieve JavaScript evaluation results.", helper.hasValue());
503         return helper.getJsonResultAndClear();
504     }
505
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);
515         ViewPair viewPair =
516                 createViewsOnMainSync(helperBridge0, helperBridge1, uiClient0, uiClient1,
517                         resourceClient0, resourceClient1, getActivity());
518
519         return viewPair;
520     }
521
522     protected String getUrlOnUiThread() throws Exception {
523         return runTestOnUiThreadAndGetResult(new Callable<String>() {
524             @Override
525             public String call() throws Exception {
526                 return mXWalkView.getUrl();
527             }
528         });
529     }
530
531     protected void clearCacheOnUiThread(final boolean includeDiskFiles) throws Exception {
532         getInstrumentation().runOnMainSync(new Runnable() {
533             @Override
534             public void run() {
535                 mXWalkView.clearCache(includeDiskFiles);
536             }
537         });
538     }
539
540     protected String getAPIVersionOnUiThread() throws Exception {
541         return runTestOnUiThreadAndGetResult(new Callable<String>() {
542             @Override
543             public String call() throws Exception {
544                 return mXWalkView.getAPIVersion();
545             }
546         });
547     }
548
549     protected String getXWalkVersionOnUiThread() throws Exception {
550         return runTestOnUiThreadAndGetResult(new Callable<String>() {
551             @Override
552             public String call() throws Exception {
553                 return mXWalkView.getXWalkVersion();
554             }
555         });
556     }
557 }