http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/androidTest/java/org/apache/cordova/unittests/IFrameTest.java ---------------------------------------------------------------------- diff --git a/test/app/src/androidTest/java/org/apache/cordova/unittests/IFrameTest.java b/test/app/src/androidTest/java/org/apache/cordova/unittests/IFrameTest.java new file mode 100644 index 0000000..f3f66d7 --- /dev/null +++ b/test/app/src/androidTest/java/org/apache/cordova/unittests/IFrameTest.java @@ -0,0 +1,114 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + + +package org.apache.cordova.unittests; + +import android.content.Intent; +import android.support.test.espresso.web.webdriver.Locator; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import org.apache.cordova.CordovaWebView; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static android.support.test.espresso.Espresso.onView; +import static android.support.test.espresso.action.ViewActions.click; +import static android.support.test.espresso.action.ViewActions.pressBack; +import static android.support.test.espresso.matcher.ViewMatchers.withId; +import static android.support.test.espresso.web.sugar.Web.onWebView; +import static android.support.test.espresso.web.webdriver.DriverAtoms.findElement; +import static android.support.test.espresso.web.webdriver.DriverAtoms.webClick; +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertTrue; +import static junit.framework.Assert.fail; + +@RunWith(AndroidJUnit4.class) +public class IFrameTest { + + private static final String START_URL = "file:///android_asset/www/iframe/index.html"; + //I have no idea why we picked 100, but we did. + private static final int WEBVIEW_ID = 100; + private int WEBVIEW_LOAD_DELAY = 500; + + private TestActivity testActivity; + + // Don't launch the activity, we're going to send it intents + @Rule + public ActivityTestRule mActivityRule = new ActivityTestRule<>( + TestActivity.class, true, false); + + @Before + public void launchApplicationWithIntent() { + Intent intent = new Intent(); + intent.putExtra("startUrl", START_URL); + testActivity = (TestActivity) mActivityRule.launchActivity(intent); + } + + @Test + public void iFrameHistory() throws Throwable { + final CordovaWebView cordovaWebView = (CordovaWebView) testActivity.getWebInterface(); + onWebView().withElement(findElement(Locator.ID, "google_maps")).perform(webClick()); + sleep(WEBVIEW_LOAD_DELAY); + mActivityRule.runOnUiThread(new Runnable() { + public void run() + { + String url = cordovaWebView.getUrl(); + assertTrue(url.endsWith("index.html")); + } + }); + sleep(WEBVIEW_LOAD_DELAY); + onWebView().withElement(findElement(Locator.ID, "javascript_load")).perform(webClick()); + mActivityRule.runOnUiThread(new Runnable() { + public void run() + { + String url = cordovaWebView.getUrl(); + assertTrue(url.endsWith("index.html")); + } + }); + sleep(WEBVIEW_LOAD_DELAY); + //Espresso will kill the application and not trigger the backHistory method, which correctly + //navigates the iFrame history. backHistory is tied to the back button. + mActivityRule.runOnUiThread(new Runnable() { + public void run() + { + assertTrue(cordovaWebView.backHistory()); + String url = cordovaWebView.getUrl(); + assertTrue(url.endsWith("index.html")); + assertFalse(cordovaWebView.backHistory()); + } + }); + + } + + + //BRUTE FORCE THE CRAP OUT OF CONCURRENCY ERRORS + private void sleep(int timeout) { + try { + Thread.sleep(timeout); + } catch (InterruptedException e) { + fail("Unexpected Timeout"); + } + } + +}
http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/androidTest/java/org/apache/cordova/unittests/MessageChannelMultipageTest.java ---------------------------------------------------------------------- diff --git a/test/app/src/androidTest/java/org/apache/cordova/unittests/MessageChannelMultipageTest.java b/test/app/src/androidTest/java/org/apache/cordova/unittests/MessageChannelMultipageTest.java new file mode 100644 index 0000000..e1d473b --- /dev/null +++ b/test/app/src/androidTest/java/org/apache/cordova/unittests/MessageChannelMultipageTest.java @@ -0,0 +1,111 @@ +package org.apache.cordova.unittests; + +import android.content.Intent; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; + +import org.apache.cordova.CallbackContext; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.CordovaWebViewImpl; +import org.apache.cordova.PluginManager; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import java.lang.reflect.Field; +import java.lang.reflect.Method; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.fail; + +@RunWith(AndroidJUnit4.class) +public class MessageChannelMultipageTest { + private static final String START_URL = "file:///android_asset/www/backbuttonmultipage/index.html"; + //I have no idea why we picked 100, but we did. + private static final int WEBVIEW_ID = 100; + private TestActivity testActivity; + + @Rule + public ActivityTestRule mActivityRule = new ActivityTestRule<>( + TestActivity.class); + + @Before + public void launchApplicationWithIntent() { + Intent intent = new Intent(); + intent.putExtra("startUrl", START_URL); + testActivity = (TestActivity) mActivityRule.launchActivity(intent); + } + + + + //test that after a page load the cached callback id and the live callback id match + //this is to prevent a regression + //the issue was that CordovaWebViewImpl's cached instance of CoreAndroid would become stale on page load + //this is because the cached instance was not being cleared when the pluginManager was reset on page load + //the plugin manager would get a new instance which would be updated with a new callback id + //the cached instance's message channel callback id would become stale + //effectively this caused message channel events to not be delivered + @Test + public void testThatCachedCallbackIdIsValid() throws Throwable { + final CordovaWebView cordovaWebView = testActivity.getWebInterface(); + Class cordovaWebViewImpl = CordovaWebViewImpl.class; + //send a test event - this initializes cordovaWebViewImpl.appPlugin (the cached instance of CoreAndroid) + Method method = cordovaWebViewImpl.getDeclaredMethod("sendJavascriptEvent", String.class); + method.setAccessible(true); + method.invoke(cordovaWebView, "testEvent"); + sleep(1000); + + //load a page - this resets the plugin manager and nulls cordovaWebViewImpl.appPlugin + //(previously this resets plugin manager but did not null cordovaWebViewImpl.appPlugin, leading to the issue) + mActivityRule.runOnUiThread(new Runnable() { + public void run() { + cordovaWebView.loadUrl(START_URL); + } + }); + assertEquals(START_URL, testActivity.onPageFinishedUrl.take()); + + //send a test event - this initializes cordovaWebViewImpl.appPlugin (the cached instance of CoreAndroid) + method.invoke(cordovaWebView, "testEvent"); + sleep(1000); + + //get reference to package protected class CoreAndroid + Class coreAndroid = Class.forName("org.apache.cordova.CoreAndroid"); + + //get cached CoreAndroid + Field appPluginField = cordovaWebViewImpl.getDeclaredField("appPlugin"); + appPluginField.setAccessible(true); + Object cachedAppPlugin = appPluginField.get(cordovaWebView); + //get cached CallbackContext + Field messageChannelField = coreAndroid.getDeclaredField("messageChannel"); + messageChannelField.setAccessible(true); + CallbackContext cachedCallbackContext = (CallbackContext) messageChannelField.get(cachedAppPlugin); + + //get live CoreAndroid + PluginManager pluginManager = cordovaWebView.getPluginManager(); + Field coreAndroidPluginNameField = coreAndroid.getField("PLUGIN_NAME"); + String coreAndroidPluginName = (String) coreAndroidPluginNameField.get(null); + Object liveAppPlugin = pluginManager.getPlugin(coreAndroidPluginName); + //get live CallbackContext + CallbackContext liveCallbackContext = (CallbackContext) messageChannelField.get(liveAppPlugin); + + //get callback id from live callbackcontext + String liveCallbackId = (liveCallbackContext != null) ? liveCallbackContext.getCallbackId() : null; + //get callback id from cached callbackcontext + String cachedCallbackId = (cachedCallbackContext != null) ? cachedCallbackContext.getCallbackId() : null; + + //verify that the live message channel has been initialized + assertNotNull(liveCallbackId); + //verify that the cached message channel and the live message channel have the same id + assertEquals(liveCallbackId, cachedCallbackId); + } + + private void sleep(int timeout) { + try { + Thread.sleep(timeout); + } catch (InterruptedException e) { + fail("Unexpected Timeout"); + } + } +} http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/androidTest/java/org/apache/cordova/unittests/StandardActivityTest.java ---------------------------------------------------------------------- diff --git a/test/app/src/androidTest/java/org/apache/cordova/unittests/StandardActivityTest.java b/test/app/src/androidTest/java/org/apache/cordova/unittests/StandardActivityTest.java new file mode 100644 index 0000000..f7162d5 --- /dev/null +++ b/test/app/src/androidTest/java/org/apache/cordova/unittests/StandardActivityTest.java @@ -0,0 +1,100 @@ +/* + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +*/ + +package org.apache.cordova.unittests; + +import android.content.Intent; +import android.graphics.Color; +import android.support.test.rule.ActivityTestRule; +import android.support.test.runner.AndroidJUnit4; +import android.view.View; +import android.widget.LinearLayout; + +import org.apache.cordova.CordovaPreferences; +import org.apache.cordova.CordovaWebView; +import org.apache.cordova.engine.SystemWebView; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.runner.RunWith; + +import static junit.framework.Assert.assertEquals; +import static junit.framework.Assert.assertFalse; +import static junit.framework.Assert.assertNotNull; +import static junit.framework.Assert.assertNotSame; +import static junit.framework.Assert.assertTrue; + +/** + * The purpose of this test is to test the default application that is generated by Cordova itself + * + */ +@RunWith(AndroidJUnit4.class) +public class StandardActivityTest { + + private static final String FALSE_URI = "http://www.google.com"; + + // Don't launch the activity, we're going to send it intents + @Rule + public ActivityTestRule mActivityRule = new ActivityTestRule<>( + StandardActivity.class, true, false); + + @Before + public void launchApplicationWithIntent() { + Intent intent = new Intent(); + intent.putExtra("startUrl", FALSE_URI); + intent.putExtra("backgroundcolor", "#0000ff"); + mActivityRule.launchActivity(intent); + } + + + @Test + public void webViewCheck() { + StandardActivity activity = (StandardActivity) mActivityRule.getActivity(); + //Fish the webview out of the mostly locked down Activity using the Android SDK + View view = activity.getWindow().getCurrentFocus(); + assertEquals(SystemWebView.class, view.getClass()); + } + + @Test + public void startUriIntentCheck() { + StandardActivity activity = (StandardActivity) mActivityRule.getActivity(); + final SystemWebView webView = (SystemWebView) activity.getWindow().getCurrentFocus(); + try { + mActivityRule.runOnUiThread(new Runnable() { + @Override + public void run() { + String uri = webView.getUrl(); + assertFalse(uri.equals(FALSE_URI)); + } + }); + } catch (Throwable throwable) { + throwable.printStackTrace(); + } + } + + @Test + public void checkBackgroundIntentCheck() { + StandardActivity activity = (StandardActivity) mActivityRule.getActivity(); + final SystemWebView webView = (SystemWebView) activity.getWindow().getCurrentFocus(); + CordovaWebView webInterface = webView.getCordovaWebView(); + CordovaPreferences prefs = webInterface.getPreferences(); + assertFalse(prefs.getInteger("backgroundcolor", Color.BLACK) == Color.GREEN); + } + +} http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/main/AndroidManifest.xml ---------------------------------------------------------------------- diff --git a/test/app/src/main/AndroidManifest.xml b/test/app/src/main/AndroidManifest.xml new file mode 100644 index 0000000..86bc83c --- /dev/null +++ b/test/app/src/main/AndroidManifest.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8"?> +<manifest xmlns:android="http://schemas.android.com/apk/res/android" + package="org.apache.cordova.unittests"> + + <application + android:allowBackup="true" + android:icon="@mipmap/ic_launcher" + android:label="@string/app_name" + android:supportsRtl="true" + android:theme="@style/AppTheme"> + <activity android:name=".EmbeddedWebViewActivity" + android:configChanges="orientation|keyboardHidden" + android:label="@string/app_name" + android:windowSoftInputMode="adjustPan"> + <intent-filter > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name=".StandardActivity" + android:configChanges="orientation|keyboardHidden" + android:label="@string/app_name" + android:windowSoftInputMode="adjustPan"> + <intent-filter > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + <activity android:name=".TestActivity" + android:configChanges="orientation|keyboardHidden" + android:label="@string/app_name" + android:windowSoftInputMode="adjustPan"> + <intent-filter > + <action android:name="android.intent.action.MAIN" /> + <category android:name="android.intent.category.LAUNCHER" /> + </intent-filter> + </activity> + </application> + +</manifest> \ No newline at end of file http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/main/assets/www/backbuttonmultipage/index.html ---------------------------------------------------------------------- diff --git a/test/app/src/main/assets/www/backbuttonmultipage/index.html b/test/app/src/main/assets/www/backbuttonmultipage/index.html new file mode 100755 index 0000000..8739aa0 --- /dev/null +++ b/test/app/src/main/assets/www/backbuttonmultipage/index.html @@ -0,0 +1,40 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<title>Backbutton</title> +<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title"> +<script type="text/javascript" charset="utf-8" src="../cordova.js"></script> +<script type="text/javascript" charset="utf-8" src="../main.js"></script> + +<body onload="init();" id="stage" class="theme"> + <h1>Cordova Android Tests</h1> + <div id="info"> + <h4>Cordova: <span id="cordova"> </span></h4> + <h4>Deviceready: <span id="deviceready"> </span></h4> + </div> + <div id="info"> + <h4>Page 1</h4> + Go to next page.<br> + If returning from previous page, press "backbutton". You should exit this app. + </div> + <a href="sample2.html" class="btn large">Next page</a> +</body> +</html> http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/main/assets/www/backbuttonmultipage/sample2.html ---------------------------------------------------------------------- diff --git a/test/app/src/main/assets/www/backbuttonmultipage/sample2.html b/test/app/src/main/assets/www/backbuttonmultipage/sample2.html new file mode 100755 index 0000000..0b5be64 --- /dev/null +++ b/test/app/src/main/assets/www/backbuttonmultipage/sample2.html @@ -0,0 +1,40 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<title>Backbutton</title> +<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title"> +<script type="text/javascript" charset="utf-8" src="../cordova.js"></script> +<script type="text/javascript" charset="utf-8" src="../main.js"></script> + +<body onload="init();" id="stage" class="theme"> + <h1>Cordova Android Tests</h1> + <div id="info"> + <h4>Cordova: <span id="cordova"> </span></h4> + <h4>Deviceready: <span id="deviceready"> </span></h4> + </div> + <div id="info"> + <h4>Page 2</h4> + Go to next page.<br> + If returning from previous page, press "backbutton". You should go to Page 1. + </div> + <a href="sample3.html" class="btn large">Next page</a> +</body> +</html> http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/main/assets/www/backbuttonmultipage/sample3.html ---------------------------------------------------------------------- diff --git a/test/app/src/main/assets/www/backbuttonmultipage/sample3.html b/test/app/src/main/assets/www/backbuttonmultipage/sample3.html new file mode 100755 index 0000000..7aa1e3b --- /dev/null +++ b/test/app/src/main/assets/www/backbuttonmultipage/sample3.html @@ -0,0 +1,42 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<html> +<head> +<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> +<title>Backbutton</title> +<link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title"> +<script type="text/javascript" charset="utf-8" src="../cordova.js"></script> +<script type="text/javascript" charset="utf-8" src="../main.js"></script> + +<body onload="init();" id="stage" class="theme"> + <h1>Cordova Android Tests</h1> + <div id="info"> + <h4>Cordova: <span id="cordova"> </span></h4> + <h4>Deviceready: <span id="deviceready"> </span></h4> + </div> + <div id="info"> + <h4>Page 3</h4> + Press the 3 buttons below. You should stay on same page.<br> + Press "backbutton" 4 times. This will go back to #test3, #test2, #test1, then return to previous Page 2.<br> + </div> + <a href="sample3.html#test1" class="btn large">page3#test1</a> + <a href="sample3.html#test2" class="btn large">page3#test2</a> + <a href="sample3.html#test3" class="btn large">page3#test3</a> +</body> +</html> http://git-wip-us.apache.org/repos/asf/cordova-android/blob/3bbc7fb3/test/app/src/main/assets/www/backgroundcolor/index.html ---------------------------------------------------------------------- diff --git a/test/app/src/main/assets/www/backgroundcolor/index.html b/test/app/src/main/assets/www/backgroundcolor/index.html new file mode 100755 index 0000000..3b09d64 --- /dev/null +++ b/test/app/src/main/assets/www/backgroundcolor/index.html @@ -0,0 +1,39 @@ +<!-- + Licensed to the Apache Software Foundation (ASF) under one + or more contributor license agreements. See the NOTICE file + distributed with this work for additional information + regarding copyright ownership. The ASF licenses this file + to you under the Apache License, Version 2.0 (the + "License"); you may not use this file except in compliance + with the License. You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, + software distributed under the License is distributed on an + "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + KIND, either express or implied. See the License for the + specific language governing permissions and limitations + under the License. +--> +<!DOCTYPE HTML> +<html> + <head> + <meta name="viewport" content="width=320, user-scalable=no" /> + <meta http-equiv="Content-type" content="text/html; charset=utf-8"> + <title>Cordova Tests</title> + <link rel="stylesheet" href="../master.css" type="text/css" media="screen" title="no title"> + <script type="text/javascript" charset="utf-8" src="../cordova.js"></script> + <script type="text/javascript" charset="utf-8" src="../main.js"></script> + </head> + <body onload="init();" id="stage" class="theme"> + <h1>Background Color Test</h1> + <div id="info"> + <h4>Cordova: <span id="cordova"> </span></h4> + <h4>Deviceready: <span id="deviceready"> </span></h4> + </div> + <div id="info"> + Before this page was show, you should have seen the background flash green.</br> + </div> + </body> +</html> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
