Compare commits

..

29 Commits

Author SHA1 Message Date
filmaj 8fc099b8f1 CB-12546: tweak parsing of avdmanager output to match the old output from android list avd. also explicitly set the CWD of the spawned emulator process to workaround a recent google android sdk bug. 2017-03-08 09:12:44 -08:00
filmaj 73f28541ab CB-12546: start of work on parsing emulator info from avdmanager output. work in progress. 2017-03-07 17:04:11 -08:00
Bharath Hariharan 7d5afdebe1 Updating version
This closes #364
2017-02-27 16:03:44 -08:00
Joe Bowser 3bbc7fb328 CB-12465: Writing new JUnit Test Instrumentation to replace tests and retire problmatic tests
This closes #363
2017-02-27 09:28:02 -08:00
Bharath Hariharan ac6ad2dea1 Adding Binary plugin to class path
This closes #361
2017-02-22 16:47:59 -08:00
Bharath Hariharan 0b116f1b5c Updating Maven settings 2017-02-14 16:31:27 -08:00
Bharath Hariharan acdb934ef9 Add the ability to publish to Bintray jCenter repo 2017-02-13 16:37:39 -08:00
Steve Gill 5591a1a4e8 Update JS snapshot to version 6.2.0-dev (via coho) 2017-01-26 16:30:33 -08:00
Steve Gill 124574bb3a Set VERSION to 6.2.0-dev (via coho) 2017-01-26 16:30:31 -08:00
Steve Gill a2cfaab7f4 CB-12403 Updated RELEASENOTES and Version for release 6.1.2 2017-01-26 15:21:50 -08:00
Joe Bowser 6355425a6f Change to https by default 2017-01-20 09:31:31 -08:00
audreyso 2d96995801 CB:12018 : added dev dependencies to gitignore
This closes #355
2017-01-17 09:38:14 -08:00
audreyso 3fc4daa447 CB-12018 : updated tests to work with jasmine (promise matcher tests commented out for now) 2017-01-11 17:07:17 -08:00
Julio César c7ff24b983 Closing invalid pull request: close #350 2017-01-10 19:22:44 +01:00
Jesse MacFadyen 3f674faf30 Merge branch 'CB-5968' of https://github.com/sterlingann/cordova-android 2017-01-08 22:42:18 -08:00
Steve Gill b9ad1b6b26 Update JS snapshot to version 6.2.0-dev (via coho) 2017-01-03 17:45:55 -08:00
Steve Gill 676f0ddc2e CB-12314 updated release notes for 6.1.1 release 2017-01-03 17:45:15 -08:00
daserge 6c60dc5dc8 CB-12159 Android: Keystore password prompt won't show up
This closes #351
2016-12-08 09:51:24 -08:00
Joe Bowser 1af5ade39a Adding isClean to the spec, this really should have failed a few commits ago
This closes #349
2016-12-05 15:32:18 -08:00
Joe Bowser ad40d33400 Need to pass lint 2016-11-21 16:36:20 -08:00
Joe Bowser 5017e2302b CB-12169: Check for build directory before running a clean 2016-11-21 14:46:09 -08:00
Joe Bowser 3bfeda4a3b Updating the timeout due to known travis issues 2016-11-03 11:35:42 -07:00
Jesse MacFadyen 348b1b4dda Do not test for non-existent build folder
This closes #348
2016-11-03 11:23:05 -07:00
Jesse MacFadyen 0fd7e7f040 Fixed AndroidStudio tests to actually run, removed app/src/main/assets/ as a requirement and added app/src/main/res instead, added placeholder for build/ folder, Removed dupe gitignore 2016-11-02 19:46:33 -07:00
Joe Bowser cfa0fa7243 Update JS snapshot to version 6.2.0-dev (via coho) 2016-11-02 16:32:16 -07:00
Joe Bowser 6a63d9df0a Set VERSION to 6.2.0-dev (via coho) 2016-11-02 16:32:15 -07:00
Sterling d6a1d7a913 updated xxhdpi mipmap icon to 144x144 2016-10-28 21:57:54 -07:00
Sterling 700b425774 replaced with unstretched images 2016-10-28 17:20:56 -07:00
Sterling e31634b0fb created directories and corresponding images for xxhdpi and xxxhdpi, both drawables and mipmaps 2016-10-28 17:03:45 -07:00
102 changed files with 3670 additions and 2531 deletions
+1 -1
View File
@@ -1 +1 @@
6.1.2
6.2.0-dev
+14
View File
@@ -62,3 +62,17 @@ module.exports.run = function() {
return Q.all([get_sdks()]);
};
module.exports.version_string_to_api_level = {
"4.0": 14,
"4.0.3": 15,
"4.1": 16,
"4.2": 17,
"4.3": 18,
"4.4": 19,
"4.4W": 20,
"5.0": 21,
"5.1": 22,
"6.0": 23,
"7.0": 24,
"7.1": 25
};
+107 -20
View File
@@ -22,6 +22,7 @@
/* jshint sub:true */
var retry = require('./retry');
var android_sdk = require('./android_sdk_version');
var build = require('./build');
var path = require('path');
var Adb = require('./Adb');
@@ -29,9 +30,11 @@ var AndroidManifest = require('./AndroidManifest');
var events = require('cordova-common').events;
var spawn = require('cordova-common').superspawn.spawn;
var CordovaError = require('cordova-common').CordovaError;
var shelljs = require('shelljs');
var Q = require('q');
var os = require('os');
var fs = require('fs');
var child_process = require('child_process');
// constants
@@ -42,18 +45,16 @@ var NUM_INSTALL_RETRIES = 3;
var CHECK_BOOTED_INTERVAL = 3 * ONE_SECOND; // in milliseconds
var EXEC_KILL_SIGNAL = 'SIGKILL';
/**
* Returns a Promise for a list of emulator images in the form of objects
* {
name : <emulator_name>,
path : <path_to_emulator_image>,
target : <api_target>,
abi : <cpu>,
skin : <skin>
}
*/
module.exports.list_images = function() {
return spawn('android', ['list', 'avds'])
function forgivingWhichSync(cmd) {
try {
return fs.realpathSync(shelljs.which(cmd));
} catch (e) {
return '';
}
}
function list_images_using_avdmanager() {
return spawn('avdmanager', ['list', 'avd'])
.then(function(output) {
var response = output.split('\n');
var emulator_list = [];
@@ -70,14 +71,30 @@ module.exports.list_images = function() {
i++;
img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
}
if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) {
if (response[i + 1].match(/Target:\s/)) {
var api = response[i + 1].split('Target: ')[1];
i++;
var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : '';
img_obj['target'] = (response[i] + secondLine).split('Target: ')[1].replace('\r', '');
}
if (response[i + 1].match(/ABI:\s/)) {
i++;
img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
if (response[i + 1].match(/ABI:\s/)) {
img_obj['abi'] = response[i + 1].split('ABI: ')[1].replace('\r', '');
}
// This next conditional just aims to match the old output of `android list avd`
// We do so so that we don't have to change the logic when parsing for the
// best emulator target to spawn (see below in `best_image`)
// This allows us to transitionally support both `android` and `avdmanager` binaries,
// depending on what SDK version the user has
if (response[i + 1].match(/Based\son:\s/)) {
img_obj['target'] = response[i + 1].split('Based on:')[1];
if (img_obj['target'].match(/Tag\/ABI:\s/)) {
img_obj['target'] = img_obj['target'].split('Tag/ABI:')[0].replace('\r', '').trim();
if (img_obj['target'].indexOf('(') > -1) {
img_obj['target'] = img_obj['target'].substr(0, img_obj['target'].indexOf('(') - 1).trim();
}
}
var version_string = img_obj['target'].replace(/Android\s+/, '');
if (android_sdk.version_string_to_api_level[version_string]) {
img_obj['target'] += ' (API level ' + android_sdk.version_string_to_api_level[version_string] + ')';
}
}
}
if (response[i + 1].match(/Skin:\s/)) {
i++;
@@ -94,6 +111,73 @@ module.exports.list_images = function() {
}
return emulator_list;
});
}
/**
* Returns a Promise for a list of emulator images in the form of objects
* {
name : <emulator_name>,
path : <path_to_emulator_image>,
target : <api_target>,
abi : <cpu>,
skin : <skin>
}
*/
module.exports.list_images = function() {
if (forgivingWhichSync('android')) {
return spawn('android', ['list', 'avds'])
.then(function(output) {
var response = output.split('\n');
var emulator_list = [];
for (var i = 1; i < response.length; i++) {
// To return more detailed information use img_obj
var img_obj = {};
if (response[i].match(/Name:\s/)) {
img_obj['name'] = response[i].split('Name: ')[1].replace('\r', '');
if (response[i + 1].match(/Device:\s/)) {
i++;
img_obj['device'] = response[i].split('Device: ')[1].replace('\r', '');
}
if (response[i + 1].match(/Path:\s/)) {
i++;
img_obj['path'] = response[i].split('Path: ')[1].replace('\r', '');
}
if (response[i + 1].match(/\(API\slevel\s/) || (response[i + 2] && response[i + 2].match(/\(API\slevel\s/))) {
i++;
var secondLine = response[i + 1].match(/\(API\slevel\s/) ? response[i + 1] : '';
img_obj['target'] = (response[i] + secondLine).split('Target: ')[1].replace('\r', '');
}
if (response[i + 1].match(/ABI:\s/)) {
i++;
img_obj['abi'] = response[i].split('ABI: ')[1].replace('\r', '');
}
if (response[i + 1].match(/Skin:\s/)) {
i++;
img_obj['skin'] = response[i].split('Skin: ')[1].replace('\r', '');
}
emulator_list.push(img_obj);
}
/* To just return a list of names use this
if (response[i].match(/Name:\s/)) {
emulator_list.push(response[i].split('Name: ')[1].replace('\r', '');
}*/
}
return emulator_list;
}).catch(function(stderr) {
// try to use `avdmanager` in case `android` has problems
// this likely means the target machine is using a newer version of
// the android sdk, and possibly `avdmanager` is available.
return list_images_using_avdmanager();
});
} else if (forgivingWhichSync('avdmanager')) {
return list_images_using_avdmanager();
} else {
return Q().then(function() {
throw new CordovaError('Could not find either `android` or `avdmanager` on your $PATH! Are you sure the Android SDK is installed and available?');
});
}
};
/**
@@ -199,10 +283,13 @@ module.exports.start = function(emulator_ID, boot_timeout) {
}).then(function(emulatorId) {
return self.get_available_port()
.then(function (port) {
// Figure out the directory the emulator binary runs in, and set the cwd to that directory.
// Workaround for https://code.google.com/p/android/issues/detail?id=235461
var emulator_dir = path.dirname(shelljs.which('emulator'));
var args = ['-avd', emulatorId, '-port', port];
// Don't wait for it to finish, since the emulator will probably keep running for a long time.
child_process
.spawn('emulator', args, { stdio: 'inherit', detached: true })
.spawn('emulator', args, { stdio: 'inherit', detached: true, cwd: emulator_dir })
.unref();
// wait for emulator to start
+1 -1
View File
@@ -20,7 +20,7 @@
*/
// Coho updates this line:
var VERSION = "6.1.2";
var VERSION = "6.2.0-dev";
module.exports.version = VERSION;
+1 -1
View File
@@ -19,7 +19,7 @@
under the License.
*/
;(function() {
var PLATFORM_VERSION_BUILD_LABEL = '6.1.2';
var PLATFORM_VERSION_BUILD_LABEL = '6.2.0-dev';
// file: src/scripts/require.js
/*jshint -W079 */
+1 -1
View File
@@ -30,7 +30,7 @@ buildscript {
// http://tools.android.com/tech-docs/new-build-system/version-compatibility
// and https://issues.apache.org/jira/browse/CB-8143
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
classpath 'com.android.tools.build:gradle:2.2.3'
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

+89 -16
View File
@@ -16,28 +16,32 @@
under the License.
*/
buildscript {
repositories {
mavenCentral()
jcenter();
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
}
}
apply plugin: 'com.android.library'
ext {
apply from: 'cordova.gradle'
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
}
buildscript {
repositories {
mavenCentral()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.3'
classpath 'com.github.dcendents:android-maven-gradle-plugin:1.5'
classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.7.3'
}
}
apply plugin: 'com.android.library'
apply plugin: 'com.github.dcendents.android-maven'
apply plugin: 'com.jfrog.bintray'
group = 'org.apache.cordova'
version = '6.2.0'
android {
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
@@ -59,4 +63,73 @@ android {
assets.srcDirs = ['assets']
}
}
packagingOptions {
exclude 'META-INF/LICENSE'
exclude 'META-INF/LICENSE.txt'
exclude 'META-INF/DEPENDENCIES'
exclude 'META-INF/NOTICE'
}
}
install {
repositories.mavenInstaller {
pom {
project {
packaging 'aar'
name 'Cordova'
url 'https://cordova.apache.org'
licenses {
license {
name 'The Apache Software License, Version 2.0'
url 'http://www.apache.org/licenses/LICENSE-2.0.txt'
}
}
developers {
developer {
id 'stevengill'
name 'Steve Gill'
}
}
scm {
connection 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
developerConnection 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
url 'https://git-wip-us.apache.org/repos/asf?p=cordova-android'
}
}
}
}
}
task sourcesJar(type: Jar) {
from android.sourceSets.main.java.srcDirs
classifier = 'sources'
}
artifacts {
archives sourcesJar
}
bintray {
user = System.getenv('BINTRAY_USER')
key = System.getenv('BINTRAY_KEY')
configurations = ['archives']
pkg {
repo = 'maven'
name = 'cordova-android'
userOrg = 'cordova'
licenses = ['Apache-2.0']
vcsUrl = 'https://git-wip-us.apache.org/repos/asf?p=cordova-android.git'
websiteUrl = 'https://cordova.apache.org'
issueTrackerUrl = 'https://issues.apache.org/jira/browse/CB'
publicDownloadNumbers = true
licenses = ['Apache-2.0']
labels = ['android', 'cordova', 'phonegap']
version {
name = '6.2.0'
released = new Date()
vcsTag = '6.2.0'
}
}
}
@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
* are not expected to implement it.
*/
public interface CordovaWebView {
public static final String CORDOVA_VERSION = "6.1.2";
public static final String CORDOVA_VERSION = "6.2.0-dev";
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "cordova-android",
"version": "6.1.2",
"version": "6.2.0-dev",
"description": "cordova-android release",
"bin": {
"create": "bin/create"
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="con" path="com.android.ide.eclipse.adt.ANDROID_FRAMEWORK"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.LIBRARIES"/>
<classpathentry exported="true" kind="con" path="com.android.ide.eclipse.adt.DEPENDENCIES"/>
<classpathentry kind="src" path="src"/>
<classpathentry kind="src" path="gen"/>
<classpathentry kind="output" path="bin/classes"/>
</classpath>
+9
View File
@@ -0,0 +1,9 @@
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
.externalNativeBuild
-33
View File
@@ -1,33 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>CordovaViewTestActivity</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>com.android.ide.eclipse.adt.ResourceManagerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.PreCompilerBuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>com.android.ide.eclipse.adt.ApkBuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>com.android.ide.eclipse.adt.AndroidNature</nature>
<nature>org.eclipse.jdt.core.javanature</nature>
</natures>
</projectDescription>
-87
View File
@@ -1,87 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:windowSoftInputMode="adjustPan"
package="org.apache.cordova.test" android:versionName="1.0" android:versionCode="1">
<supports-screens
android:largeScreens="true"
android:normalScreens="true"
android:smallScreens="true"
android:xlargeScreens="true"
android:resizeable="true"
android:anyDensity="true"
/>
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.RECEIVE_SMS" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.RECORD_VIDEO"/>
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.READ_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_CONTACTS" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="android.permission.BROADCAST_STICKY" />
<uses-sdk android:minSdkVersion="16" android:targetSdkVersion="24"/>
<instrumentation
android:name="android.test.InstrumentationTestRunner"
android:targetPackage="org.apache.cordova.test" />
<application
android:icon="@drawable/icon"
android:label="@string/app_name" >
<uses-library android:name="android.test.runner" />
<activity
android:windowSoftInputMode="adjustPan"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden"
android:name="org.apache.cordova.test.CordovaWebViewTestActivity" >
<intent-filter >
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:windowSoftInputMode="adjustPan"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden"
android:name="org.apache.cordova.test.MainTestActivity" >
</activity>
<activity
android:windowSoftInputMode="adjustPan"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden"
android:name="org.apache.cordova.test.menus" >
</activity>
<activity
android:windowSoftInputMode="adjustPan"
android:label="@string/app_name"
android:configChanges="orientation|keyboardHidden"
android:name="org.apache.cordova.test.userwebview" >
</activity>
</application>
</manifest>
-61
View File
@@ -1,61 +0,0 @@
<!--
#
# 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.
#
-->
# Android Native Tests
These tests are designed to verify Android native features and other Android specific features.
## Initial Setup
### Setting env vars
Run:
../bin/check_reqs
Use the output to set your `ANDROID_HOME` and `JAVA_HOME` environment variables.
### Adding `gradlew`
Copy it from a freshly created project:
../bin/create foo
(cd foo && cordova/build --gradle; cp -r gradlew gradle ..)
rm -r foo
## Running
To run manual tests:
./gradlew installDebug
To run unit tests:
./gradlew connectedAndroidTest
`BUILD SUCCESSFUL` means that the tests all passed :)
## Android Studio
1. Use "Import Project" and import the `test` directory.
2. Right click on the `org.apache.cordova.test` package on the left-hand nav.
3. Select `Create Run Configuration` -> `Tests in ...` (The one with the Android icon)
4. Review options (mainly - target device)
5. Click the bug icon in the top toolbar to run with debugger attached
@@ -1,194 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
import android.view.KeyEvent;
import android.view.inputmethod.BaseInputConnection;
public class BackButtonMultiPageTest extends BaseCordovaIntegrationTest {
private static final String START_URL = "file:///android_asset/www/backbuttonmultipage/index.html";
@Override
public void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(START_URL);
}
public void testViaHref() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.sendJavascript("window.location = 'sample2.html';");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.sendJavascript("window.location = 'sample3.html';"); }
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
assertTrue(cordovaWebView.backHistory());
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
assertTrue(cordovaWebView.backHistory());
}
});
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
assertFalse(cordovaWebView.backHistory());
}
});
}
public void testViaLoadUrl() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.loadUrl("file:///android_asset/www/backbuttonmultipage/sample2.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.loadUrl("file:///android_asset/www/backbuttonmultipage/sample3.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
assertTrue(cordovaWebView.backHistory());
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
assertTrue(cordovaWebView.backHistory());
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/index.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
assertFalse(cordovaWebView.backHistory());
}
});
}
public void testViaBackButtonOnView() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
cordovaWebView.loadUrl("file:///android_asset/www/backbuttonmultipage/sample2.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
cordovaWebView.loadUrl("file:///android_asset/www/backbuttonmultipage/sample3.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
String url = cordovaWebView.getUrl();
assertTrue(url.endsWith("sample3.html"));
BaseInputConnection viewConnection = new BaseInputConnection(cordovaWebView.getView(), true);
KeyEvent backDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
KeyEvent backUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
viewConnection.sendKeyEvent(backDown);
viewConnection.sendKeyEvent(backUp);
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
String url = cordovaWebView.getUrl();
assertTrue(url.endsWith("sample2.html"));
BaseInputConnection viewConnection = new BaseInputConnection(cordovaWebView.getView(), true);
KeyEvent backDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
KeyEvent backUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
viewConnection.sendKeyEvent(backDown);
viewConnection.sendKeyEvent(backUp);
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/index.html", testActivity.onPageFinishedUrl.take());
}
public void testViaBackButtonOnLayout() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
cordovaWebView.loadUrl("file:///android_asset/www/backbuttonmultipage/sample2.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
cordovaWebView.loadUrl("file:///android_asset/www/backbuttonmultipage/sample3.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
String url = cordovaWebView.getUrl();
assertTrue(url.endsWith("sample3.html"));
BaseInputConnection viewConnection = new BaseInputConnection(containerView, true);
KeyEvent backDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
KeyEvent backUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
viewConnection.sendKeyEvent(backDown);
viewConnection.sendKeyEvent(backUp);
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
String url = cordovaWebView.getUrl();
assertTrue(url.endsWith("sample2.html"));
BaseInputConnection viewConnection = new BaseInputConnection(containerView, true);
KeyEvent backDown = new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_BACK);
KeyEvent backUp = new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_BACK);
viewConnection.sendKeyEvent(backDown);
viewConnection.sendKeyEvent(backUp);
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/index.html", testActivity.onPageFinishedUrl.take());
}
}
@@ -1,52 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
import android.content.Intent;
import android.test.ActivityInstrumentationTestCase2;
import android.widget.FrameLayout;
import org.apache.cordova.CordovaWebView;
public class BaseCordovaIntegrationTest extends ActivityInstrumentationTestCase2<MainTestActivity> {
protected MainTestActivity testActivity;
protected FrameLayout containerView;
protected CordovaWebView cordovaWebView;
public BaseCordovaIntegrationTest() {
super(MainTestActivity.class);
}
protected void setUpWithStartUrl(String url, String... prefsAndValues) {
Intent intent = new Intent(getInstrumentation().getContext(), MainTestActivity.class);
intent.putExtra("testStartUrl", url);
for (int i = 0; i < prefsAndValues.length; i += 2) {
intent.putExtra(prefsAndValues[i], prefsAndValues[i + 1]);
}
setActivityIntent(intent);
testActivity = getActivity();
containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
cordovaWebView = testActivity.getCordovaWebView();
}
}
@@ -1,48 +0,0 @@
/*
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.test;
import android.view.View;
import android.view.ViewGroup;
import android.widget.LinearLayout;
import org.apache.cordova.CordovaWebViewEngine;
import org.apache.cordova.engine.SystemWebView;
public class CordovaActivityTest extends BaseCordovaIntegrationTest {
private ViewGroup innerContainer;
private View testView;
protected void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(null);
testView = (ViewGroup)containerView.getChildAt(0);
}
public void testBasicLoad() throws Exception {
assertTrue(testView instanceof SystemWebView);
assertTrue(((CordovaWebViewEngine.EngineView)testView).getCordovaWebView() != null);
String onPageFinishedUrl = testActivity.onPageFinishedUrl.take();
assertEquals(MainTestActivity.START_URL, onPageFinishedUrl);
}
protected void createViews() {
assertTrue(testView instanceof SystemWebView);
}
}
@@ -1,68 +0,0 @@
/*
*
* 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.test;
import android.app.Activity;
import android.test.ActivityInstrumentationTestCase2;
import org.apache.cordova.CordovaWebView;
import java.io.IOException;
import java.lang.reflect.Method;
public class CordovaPluginTest extends BaseCordovaIntegrationTest {
protected void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(null);
}
private void invokeBlockingCallToLifeCycleEvent(final String lifeCycleEventName) {
testActivity.runOnUiThread( new Runnable() {
public void run() {
try {
Method method = getInstrumentation().getClass().getMethod(lifeCycleEventName, Activity.class);
method.invoke(getInstrumentation(), testActivity);
} catch (Exception e) {
fail("An Exception occurred in invokeBlockingCallToLifeCycleEvent while invoking " + lifeCycleEventName);
}
}
});
getInstrumentation().waitForIdleSync();
}
public void testPluginLifeCycle() throws IOException {
//TODO: add coverage for both cases where handleOnStart is called in CordovaActivity (onStart and init)
//currently only one of the cases is covered
//TODO: add coverage for both cases where onStart is called in CordovaWebViewImpl (handleOnStart and init)
//currently only one of the cases is covered
LifeCyclePlugin testPlugin = (LifeCyclePlugin)cordovaWebView.getPluginManager().getPlugin("LifeCycle");
testPlugin.calls = "";
// testOnStart
invokeBlockingCallToLifeCycleEvent("callActivityOnStart");
invokeBlockingCallToLifeCycleEvent("callActivityOnResume");
invokeBlockingCallToLifeCycleEvent("callActivityOnPause");
invokeBlockingCallToLifeCycleEvent("callActivityOnStop");
assertEquals("start,resume,pause,stop,", testPlugin.calls);
}
}
@@ -1,280 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Environment;
import android.provider.MediaStore;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.CordovaResourceApi.OpenForReadResult;
import org.apache.cordova.PluginEntry;
import org.json.JSONArray;
import org.json.JSONException;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.charset.StandardCharsets;
import java.util.Scanner;
public class CordovaResourceApiTest extends BaseCordovaIntegrationTest {
CordovaResourceApi resourceApi;
String execPayload;
Integer execStatus;
protected void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(null);
resourceApi = cordovaWebView.getResourceApi();
resourceApi.setThreadCheckingEnabled(false);
cordovaWebView.getPluginManager().addService(new PluginEntry("CordovaResourceApiTestPlugin1", new CordovaPlugin() {
@Override
public Uri remapUri(Uri uri) {
if (uri.getQuery() != null && uri.getQuery().contains("pluginRewrite")) {
return cordovaWebView.getResourceApi().remapUri(
Uri.parse("data:text/plain;charset=utf-8,pass"));
}
if (uri.getQuery() != null && uri.getQuery().contains("pluginUri")) {
return toPluginUri(uri);
}
return null;
}
@Override
public OpenForReadResult handleOpenForRead(Uri uri) throws IOException {
Uri orig = fromPluginUri(uri);
ByteArrayInputStream retStream = new ByteArrayInputStream(orig.toString().getBytes(StandardCharsets.UTF_8));
return new OpenForReadResult(uri, retStream, "text/plain", retStream.available(), null);
}
@Override
public boolean execute(String action, JSONArray args, CallbackContext callbackContext) throws JSONException {
synchronized (CordovaResourceApiTest.this) {
execPayload = args.getString(0);
execStatus = args.getInt(1);
CordovaResourceApiTest.this.notify();
}
return true;
}
}));
}
private Uri createTestImageContentUri() {
Bitmap imageBitmap = BitmapFactory.decodeResource(testActivity.getResources(), R.drawable.icon);
String stored = MediaStore.Images.Media.insertImage(testActivity.getContentResolver(),
imageBitmap, "app-icon", "desc");
return Uri.parse(stored);
}
private void performApiTest(Uri uri, String expectedMimeType, File expectedLocalFile,
boolean expectRead, boolean expectWrite) throws IOException {
uri = resourceApi.remapUri(uri);
assertEquals(expectedLocalFile, resourceApi.mapUriToFile(uri));
try {
OpenForReadResult readResult = resourceApi.openForRead(uri);
String mimeType2 = resourceApi.getMimeType(uri);
assertEquals("openForRead mime-type", expectedMimeType, readResult.mimeType);
assertEquals("getMimeType mime-type", expectedMimeType, mimeType2);
readResult.inputStream.read();
if (!expectRead) {
fail("Expected getInputStream to throw.");
}
} catch (IOException e) {
if (expectRead) {
throw e;
}
}
try {
OutputStream outStream = resourceApi.openOutputStream(uri);
outStream.write(123);
if (!expectWrite) {
fail("Expected getOutputStream to throw.");
}
outStream.close();
} catch (IOException e) {
if (expectWrite) {
throw e;
}
}
}
public void testJavaApis() throws IOException {
// testValidContentUri
{
Uri contentUri = createTestImageContentUri();
File localFile = resourceApi.mapUriToFile(contentUri);
assertNotNull(localFile);
performApiTest(contentUri, "image/jpeg", localFile, true, true);
}
// testInvalidContentUri
{
Uri contentUri = Uri.parse("content://media/external/images/media/999999999");
performApiTest(contentUri, null, null, false, false);
}
// testValidAssetUri
{
Uri assetUri = Uri.parse("file:///android_asset/www/index.html?foo#bar"); // Also check for stripping off ? and # correctly.
performApiTest(assetUri, "text/html", null, true, false);
}
// testInvalidAssetUri
{
Uri assetUri = Uri.parse("file:///android_asset/www/missing.html");
performApiTest(assetUri, "text/html", null, false, false);
}
// testFileUriToExistingFile
{
File f = File.createTempFile("te s t", ".txt"); // Also check for dealing with spaces.
try {
Uri fileUri = Uri.parse(f.toURI().toString() + "?foo#bar"); // Also check for stripping off ? and # correctly.
performApiTest(fileUri, "text/plain", f, true, true);
} finally {
f.delete();
}
}
// testFileUriToMissingFile
{
File f = new File(Environment.getExternalStorageDirectory() + "/somefilethatdoesntexist");
Uri fileUri = Uri.parse(f.toURI().toString());
try {
performApiTest(fileUri, null, f, false, true);
} finally {
f.delete();
}
}
// testFileUriToMissingFileWithMissingParent
{
File f = new File(Environment.getExternalStorageDirectory() + "/somedirthatismissing" + System.currentTimeMillis() + "/somefilethatdoesntexist");
Uri fileUri = Uri.parse(f.toURI().toString());
performApiTest(fileUri, null, f, false, true);
}
// testUnrecognizedUri
{
Uri uri = Uri.parse("somescheme://foo");
performApiTest(uri, null, null, false, false);
}
// testRelativeUri
{
try {
resourceApi.openForRead(Uri.parse("/foo"));
fail("Should have thrown for relative URI 1.");
} catch (Throwable t) {
}
try {
resourceApi.openForRead(Uri.parse("//foo/bar"));
fail("Should have thrown for relative URI 2.");
} catch (Throwable t) {
}
try {
resourceApi.openForRead(Uri.parse("foo.png"));
fail("Should have thrown for relative URI 3.");
} catch (Throwable t) {
}
}
// testPluginOverride
{
Uri uri = Uri.parse("plugin-uri://foohost/android_asset/www/index.html?pluginRewrite=yes");
performApiTest(uri, "text/plain", null, true, false);
}
// testMainThreadUsage
{
Uri assetUri = Uri.parse("file:///android_asset/www/index.html");
resourceApi.setThreadCheckingEnabled(true);
try {
resourceApi.openForRead(assetUri);
fail("Should have thrown for main thread check.");
} catch (Throwable t) {
}
}
// testDataUriPlain
{
Uri uri = Uri.parse("data:text/plain;charset=utf-8,pa%20ss");
OpenForReadResult readResult = resourceApi.openForRead(uri);
assertEquals("text/plain", readResult.mimeType);
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
assertEquals("pa ss", data);
}
// testDataUriBase64
{
Uri uri = Uri.parse("data:text/js;charset=utf-8;base64,cGFzcw==");
OpenForReadResult readResult = resourceApi.openForRead(uri);
assertEquals("text/js", readResult.mimeType);
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
assertEquals("pass", data);
}
// testPluginUris
{
String origUri = "http://orig/foo?pluginUri";
Uri uri = resourceApi.remapUri(Uri.parse(origUri));
OpenForReadResult readResult = resourceApi.openForRead(uri);
assertEquals("openForRead mime-type", "text/plain", readResult.mimeType);
String data = new Scanner(readResult.inputStream, "UTF-8").useDelimiter("\\A").next();
assertEquals(origUri, data);
assertEquals(origUri.length(), readResult.length);
}
}
public void testWebViewRequestIntercept() throws Throwable
{
testActivity.onPageFinishedUrl.take();
execPayload = null;
execStatus = null;
cordovaWebView.sendJavascript(
"var x = new XMLHttpRequest;\n" +
"x.open('GET', 'file:///foo?pluginRewrite=1', false);\n" +
"x.send();\n" +
"cordova.require('cordova/exec')(null,null,'CordovaResourceApiTestPlugin1', 'foo', [x.responseText, x.status])");
try {
synchronized (this) {
this.wait(2000);
}
} catch (InterruptedException e) {
}
assertEquals("pass", execPayload);
assertEquals(execStatus.intValue(), 200);
}
public void testWebViewWhiteListRejection() throws Throwable
{
testActivity.onPageFinishedUrl.take();
execPayload = null;
execStatus = null;
cordovaWebView.sendJavascript(
"var x = new XMLHttpRequest;\n" +
"x.open('GET', 'http://foo/bar', false);\n" +
"x.send();\n" +
"cordova.require('cordova/exec')(null,null,'CordovaResourceApiTestPlugin1', 'foo', [x.responseText, x.status])");
try {
synchronized (this) {
this.wait(2000);
}
} catch (InterruptedException e) {
}
assertEquals("", execPayload);
assertEquals(execStatus.intValue(), 404);
}
}
@@ -1,44 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
public class ErrorUrlTest extends BaseCordovaIntegrationTest {
private static final String START_URL = "file:///android_asset/www/htmlnotfound/index.html";
private static final String ERROR_URL = "file:///android_asset/www/htmlnotfound/error.html";
private static final String INVALID_URL = "file:///android_asset/www/invalid.html";
protected void setUp() throws Exception {
super.setUp();
// INVALID_URL tests that errorUrl and url are *not* settable via the intent.
setUpWithStartUrl(START_URL, "testErrorUrl", ERROR_URL, "errorurl", INVALID_URL, "url", INVALID_URL);
}
public void testUrl() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
assertEquals(ERROR_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run() {
assertEquals(ERROR_URL, testActivity.getCordovaWebView().getUrl());
}
});
}
}
@@ -1,46 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
public class HtmlNotFoundTest extends BaseCordovaIntegrationTest {
private static final String START_URL = "file:///android_asset/www/htmlnotfound/index.html";
protected void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(START_URL);
}
public void testUrl() throws Throwable
{
runTestOnUiThread(new Runnable() {
public void run() {
assertTrue(START_URL.equals(testActivity.getCordovaWebView().getUrl()));
}
});
//loading a not-found file causes an application error and displayError is called
//the test activity overrides displayError to add message to onPageFinishedUrl
String message = testActivity.onPageFinishedUrl.take();
assertTrue(message.contains(START_URL));
assertTrue(message.contains("ERR_FILE_NOT_FOUND"));
}
}
@@ -1,107 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
import android.test.TouchUtils;
import org.apache.cordova.test.util.Purity;
public class IFrameTest extends BaseCordovaIntegrationTest {
private static final String START_URL = "file:///android_asset/www/iframe/index.html";
private TouchUtils touch;
private Purity touchTool;
protected void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(START_URL);
touch = new TouchUtils();
touchTool = new Purity(testActivity, getInstrumentation());
}
public void testIframeDest() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.sendJavascript("loadUrl('http://maps.google.com/maps?output=embed');");
}
});
sleep(3000);
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.sendJavascript("loadUrl('index2.html')");
}
});
sleep(1000);
runTestOnUiThread(new Runnable() {
public void run()
{
String url = cordovaWebView.getUrl();
assertTrue(url.endsWith("index.html"));
}
});
}
public void testIframeHistory() throws Throwable
{
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.sendJavascript("loadUrl('http://maps.google.com/maps?output=embed');");
}
});
sleep(3000);
runTestOnUiThread(new Runnable() {
public void run()
{
cordovaWebView.sendJavascript("loadUrl('index2.html')");
}
});
sleep(1000);
runTestOnUiThread(new Runnable() {
public void run()
{
String url = cordovaWebView.getUrl();
cordovaWebView.backHistory();
}
});
sleep(1000);
runTestOnUiThread(new Runnable() {
public void run()
{
String url = cordovaWebView.getUrl();
assertTrue(url.endsWith("index.html"));
}
});
}
private void sleep(int timeout) {
try {
Thread.sleep(timeout);
} catch (InterruptedException e) {
fail("Unexpected Timeout");
}
}
}
@@ -1,56 +0,0 @@
/*
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.test;
import android.test.ActivityInstrumentationTestCase2;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import org.apache.cordova.engine.SystemWebView;
public class InflateLayoutTest extends ActivityInstrumentationTestCase2<CordovaWebViewTestActivity> {
private CordovaWebViewTestActivity testActivity;
private ViewGroup innerContainer;
private View testView;
@SuppressWarnings("deprecation")
public InflateLayoutTest()
{
super("org.apache.cordova.test",CordovaWebViewTestActivity.class);
}
protected void setUp() throws Exception {
super.setUp();
testActivity = this.getActivity();
FrameLayout containerView = (FrameLayout) testActivity.findViewById(android.R.id.content);
innerContainer = (ViewGroup)containerView.getChildAt(0);
testView = innerContainer.getChildAt(0);
}
public void testBasicLoad() throws Exception {
assertTrue(testView instanceof SystemWebView);
assertTrue(innerContainer instanceof LinearLayout);
String onPageFinishedUrl = testActivity.onPageFinishedUrl.take();
assertEquals(CordovaWebViewTestActivity.START_URL, onPageFinishedUrl);
}
}
@@ -1,44 +0,0 @@
package org.apache.cordova.test;
/*
*
* 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.
*
*/
import android.graphics.Color;
import org.apache.cordova.CordovaPreferences;
public class IntentPreferenceTest extends BaseCordovaIntegrationTest {
private static final String GREEN = Integer.toHexString(Color.GREEN);
private static final String START_URL = "file:///android_asset/www/index.html";
CordovaPreferences prefs;
protected void setUp() throws Exception {
super.setUp();
// INVALID_URL tests that errorUrl and url are *not* settable via the intent.
setUpWithStartUrl(START_URL, "backgroundcolor", GREEN);
prefs = cordovaWebView.getPreferences();
}
public void testUrl() throws Throwable {
assertEquals(START_URL, testActivity.onPageFinishedUrl.take());
assertFalse(prefs.getInteger("backgroundcolor", Color.BLACK) == Color.GREEN);
}
}
@@ -1,171 +0,0 @@
/*
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.
*/
/*
* Purity is a small set of Android utility methods that allows us to simulate touch events on
* Android applications. This is important for simulating some of the most annoying tests.
*/
package org.apache.cordova.test.util;
import android.app.Instrumentation;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Picture;
import android.os.SystemClock;
import android.util.DisplayMetrics;
import android.view.MotionEvent;
import android.webkit.WebView;
public class Purity {
Instrumentation inst;
int width, height;
float density;
Bitmap state;
boolean fingerDown = false;
public Purity(Context ctx, Instrumentation i)
{
inst = i;
DisplayMetrics display = ctx.getResources().getDisplayMetrics();
density = display.density;
width = display.widthPixels;
height = display.heightPixels;
}
/*
* WebKit doesn't give you real pixels anymore, this is done for subpixel fonts to appear on
* iOS and Android. However, Android automation requires real pixels
*/
private int getRealCoord(int coord)
{
return (int) (coord * density);
}
public int getViewportWidth()
{
return (int) (width/density);
}
public int getViewportHeight()
{
return (int) (height/density);
}
public void touch(int x, int y)
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
if(!fingerDown)
{
MotionEvent downEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);
inst.sendPointerSync(downEvent);
}
MotionEvent upEvent = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_UP, realX, realY, 0);
inst.sendPointerSync(upEvent);
}
public void touchStart(int x, int y)
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);
inst.sendPointerSync(event);
fingerDown = true;
}
//Move from the touch start
public void touchMove(int x, int y)
{
if(!fingerDown)
touchStart(x,y);
else
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_MOVE, realX, realY, 0);
inst.sendPointerSync(event);
}
}
public void touchEnd(int x, int y)
{
if(!fingerDown)
{
touch(x, y);
}
else
{
int realX = getRealCoord(x);
int realY = getRealCoord(y);
long downTime = SystemClock.uptimeMillis();
// event time MUST be retrieved only by this way!
long eventTime = SystemClock.uptimeMillis();
MotionEvent event = MotionEvent.obtain(downTime, eventTime, MotionEvent.ACTION_DOWN, realX, realY, 0);
inst.sendPointerSync(event);
fingerDown = false;
}
}
public void setBitmap(WebView view)
{
Picture p = view.capturePicture();
state = Bitmap.createBitmap(p.getWidth(), p.getHeight(), Bitmap.Config.ARGB_8888);
}
public boolean checkRenderView(WebView view)
{
if(state == null)
{
setBitmap(view);
return false;
}
else
{
Picture p = view.capturePicture();
Bitmap newState = Bitmap.createBitmap(p.getWidth(), p.getHeight(), Bitmap.Config.ARGB_8888);
boolean result = newState.equals(state);
newState.recycle();
return result;
}
}
public void clearBitmap()
{
if(state != null)
state.recycle();
}
protected void finalize()
{
clearBitmap();
}
}
+1
View File
@@ -0,0 +1 @@
/build
+35
View File
@@ -0,0 +1,35 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.2"
defaultConfig {
applicationId "org.apache.cordova.unittests"
minSdkVersion 16
targetSdkVersion 25
versionCode 1
versionName "1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
debugCompile project(path: ":CordovaLib", configuration: "debug")
releaseCompile project(path: ":CordovaLib", configuration: "release")
androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
androidTestCompile ('com.android.support.test.espresso:espresso-web:2.2.2', {
exclude group: 'com.android.support', module: 'support-annotations'
})
compile 'com.android.support:appcompat-v7:25.1.1'
testCompile 'junit:junit:4.12'
testCompile 'org.json:json:20140107'
}
+17
View File
@@ -0,0 +1,17 @@
# Add project specific ProGuard rules here.
# By default, the flags in this file are appended to flags specified
# in /Users/jbowser/Library/Android/sdk/tools/proguard/proguard-android.txt
# You can edit the include path and order by changing the proguardFiles
# directive in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# Add any project specific keep options here:
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
@@ -0,0 +1,158 @@
/*
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.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.pressBack;
import static android.support.test.espresso.matcher.ViewMatchers.withId;
import static android.support.test.espresso.web.sugar.Web.onWebView;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertTrue;
import static org.apache.cordova.unittests.R.id.cordovaWebView;
@RunWith(AndroidJUnit4.class)
public class BackButtonMultipageTest {
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 mActivity;
// 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);
mActivity = (TestActivity) mActivityRule.launchActivity(intent);
}
@Test
public void testViaHref() throws Throwable {
final CordovaWebView webInterface = mActivity.getWebInterface();
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
webInterface.sendJavascript("window.location = 'sample2.html';");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
webInterface.sendJavascript("window.location = 'sample3.html';");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertFalse(webInterface.backHistory());
}
});
}
@Test
public void testViaLoadUrl() throws Throwable {
final CordovaWebView webInterface = mActivity.getWebInterface();
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
webInterface.loadUrl("file:///android_asset/www/backbuttonmultipage/sample2.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
webInterface.loadUrl("file:///android_asset/www/backbuttonmultipage/sample3.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertTrue(webInterface.backHistory());
}
});
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertFalse(webInterface.backHistory());
}
});
}
@Test
public void testViaBackButtonOnView() throws Throwable {
final CordovaWebView webInterface = mActivity.getWebInterface();
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
webInterface.loadUrl("file:///android_asset/www/backbuttonmultipage/sample2.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
webInterface.loadUrl("file:///android_asset/www/backbuttonmultipage/sample3.html");
}
});
assertEquals("file:///android_asset/www/backbuttonmultipage/sample3.html", mActivity.onPageFinishedUrl.take());
onView(withId(WEBVIEW_ID)).perform(pressBack());
assertEquals("file:///android_asset/www/backbuttonmultipage/sample2.html", mActivity.onPageFinishedUrl.take());
onView(withId(WEBVIEW_ID)).perform(pressBack());
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
}
}
@@ -0,0 +1,53 @@
/*
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.support.test.rule.ActivityTestRule;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import static junit.framework.Assert.assertNotNull;
/*
* This test is to cover the use case of Cordova Android used as a component in a larger Android
* application. This test is strictly used to cover this use case. In this example, the WebView
* should load, not be null, and the Plugin Manager should also be initialized.
*
*/
@RunWith(AndroidJUnit4.class)
public class EmbeddedWebViewTest {
@Rule
public ActivityTestRule mActivityRule = new ActivityTestRule<>(
EmbeddedWebViewActivity.class);
@Test
public void checkWebViewTest() {
EmbeddedWebViewActivity activity = (EmbeddedWebViewActivity) mActivityRule.getActivity();
assertNotNull(activity.webInterface);
assertNotNull(activity.webInterface.getPluginManager());
}
}
@@ -0,0 +1,68 @@
/*
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.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 junit.framework.Assert.assertEquals;
@RunWith(AndroidJUnit4.class)
public class ErrorUrlTest {
private static final String START_URL = "file:///android_asset/www/htmlnotfound/index.html";
private static final String ERROR_URL = "file:///android_asset/www/htmlnotfound/error.html";
private static final String INVALID_URL = "file:///android_asset/www/invalid.html";
//I have no idea why we picked 100, but we did.
private static final int WEBVIEW_ID = 100;
private TestActivity mActivity;
@Rule
public ActivityTestRule mActivityRule = new ActivityTestRule<>(
TestActivity.class);
@Before
public void launchApplicationWithIntent() {
Intent intent = new Intent();
intent.putExtra("startUrl", START_URL);
intent.putExtra("errorurl", INVALID_URL);
intent.putExtra("url", INVALID_URL);
mActivity = (TestActivity) mActivityRule.launchActivity(intent);
}
@Test
public void errorUrlTest() throws Throwable {
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
assertEquals(ERROR_URL, mActivity.onPageFinishedUrl.take());
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
assertEquals(ERROR_URL, mActivity.getWebInterface().getUrl());
}
});
}
}
@@ -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");
}
}
}
@@ -1,45 +1,45 @@
package org.apache.cordova.test;
/*
*
* 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.view.KeyEvent;
import android.view.inputmethod.BaseInputConnection;
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;
public class MessageChannelMultiPageTest extends BaseCordovaIntegrationTest {
private static final String START_URL = "file:///android_asset/www/backbuttonmultipage/index.html";
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.fail;
@Override
public void setUp() throws Exception {
super.setUp();
setUpWithStartUrl(START_URL);
@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
@@ -47,7 +47,9 @@ public class MessageChannelMultiPageTest extends BaseCordovaIntegrationTest {
//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);
@@ -57,7 +59,7 @@ public class MessageChannelMultiPageTest extends BaseCordovaIntegrationTest {
//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)
runTestOnUiThread(new Runnable() {
mActivityRule.runOnUiThread(new Runnable() {
public void run() {
cordovaWebView.loadUrl(START_URL);
}
@@ -81,7 +83,7 @@ public class MessageChannelMultiPageTest extends BaseCordovaIntegrationTest {
CallbackContext cachedCallbackContext = (CallbackContext) messageChannelField.get(cachedAppPlugin);
//get live CoreAndroid
PluginManager pluginManager = MessageChannelMultiPageTest.this.cordovaWebView.getPluginManager();
PluginManager pluginManager = cordovaWebView.getPluginManager();
Field coreAndroidPluginNameField = coreAndroid.getField("PLUGIN_NAME");
String coreAndroidPluginName = (String) coreAndroidPluginNameField.get(null);
Object liveAppPlugin = pluginManager.getPlugin(coreAndroidPluginName);
@@ -106,5 +108,4 @@ public class MessageChannelMultiPageTest extends BaseCordovaIntegrationTest {
fail("Unexpected Timeout");
}
}
}
@@ -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);
}
}
+40
View File
@@ -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>
File diff suppressed because it is too large Load Diff
@@ -43,7 +43,7 @@
(NOTE: THIS BEHAVIOR IS WRONG - AND NEEDS TO BE FIXED IN FUTURE RELEASE.)
</div>
<iframe id="iframe" src="" width="90%" height="200px"></iframe>
<a href="javascript:" class="btn large" onclick="loadUrl('http://maps.google.com/maps?output=embed');">Google Maps</a>
<a href="javascript:" class="btn large" onclick="loadUrl('index2.html');">Page 2</a>
<a id="google_maps" href="javascript:" class="btn large" onclick="loadUrl('http://maps.google.com/maps?output=embed');">Google Maps</a>
<a id="javascript_load" href="javascript:" class="btn large" onclick="loadUrl('index2.html');">Page 2</a>
</body>
</html>
@@ -44,20 +44,13 @@
<div id="info">
<h4>Run each of the test activities below:</h4>
</div>
<button class="btn large" onclick="startActivity('jqmtabbackbutton/index.html');">Backbutton jQM tab</button>
<button class="btn large" onclick="startActivity('backbuttonmultipage/index.html');">Backbutton with multiple pages</button>
<button class="btn large" onclick="startActivity('backgroundcolor/index.html', {backgroundcolor: -16711936});">Background Color</button>
<button class="btn large" onclick="startActivity('basicauth/index.html');">Basic Authentication</button>
<button class="btn large" onclick="startActivity('errorurl/index.html', {testErrorUrl: 'file:///android_asset/www/htmlnotfound/error.html'});">Error URL</button>
<button class="btn large" onclick="startActivity('fullscreen/index.html', {fullscreen: true});">Full Screen</button>
<button class="btn large" onclick="startActivity('htmlnotfound/index.html');">HTML not found</button>
<button class="btn large" onclick="startActivity('iframe/index.html');">IFrame</button>
<button class="btn large" onclick="startActivity('lifecycle/index.html');">Lifecycle</button>
<button class="btn large" onclick="startActivity('menus/index.html', null, 'org.apache.cordova.test.menus');">Menus</button>
<button class="btn large" onclick="startActivity('background/index.html', {keeprunning: false});">No multitasking</button>
<button class="btn large" onclick="startActivity('http://www.google.com', {loadurltimeoutvalue: 10});">Load timeout</button>
<button class="btn large" onclick="startActivity('userwebview/index.html', null, 'org.apache.cordova.test.userwebview');">User WebView/Client/Chrome</button>
<button class="btn large" onclick="startActivity('whitelist/index.html');">Whitelist</button>
<button class="btn large" onclick="startActivity('xhr/index.html');">XHR</button>
</body>
</html>
@@ -0,0 +1,110 @@
/*
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.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import org.apache.cordova.ConfigXmlParser;
import org.apache.cordova.CordovaInterfaceImpl;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewImpl;
import org.apache.cordova.PluginManager;
import org.apache.cordova.engine.SystemWebView;
import org.apache.cordova.engine.SystemWebViewEngine;
import org.json.JSONException;
public class EmbeddedWebViewActivity extends AppCompatActivity {
public CordovaWebView webInterface;
private CordovaInterfaceImpl cordovaInterface = new CordovaInterfaceImpl(this);
private String TAG = "CordovaTestActivity";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//Set up the webview
ConfigXmlParser parser = new ConfigXmlParser();
parser.parse(this);
SystemWebView webView = (SystemWebView) findViewById(R.id.cordovaWebView);
webInterface = new CordovaWebViewImpl(new SystemWebViewEngine(webView));
webInterface.init(cordovaInterface, parser.getPluginEntries(), parser.getPreferences());
webView.loadUrl(parser.getLaunchUrl());
}
// This is still required by Cordova
@Override
public void onDestroy()
{
super.onDestroy();
PluginManager pluginManager = webInterface.getPluginManager();
if(pluginManager != null)
{
pluginManager.onDestroy();
}
}
/**
* Called when an activity you launched exits, giving you the requestCode you started it with,
* the resultCode it returned, and any additional data from it.
*
* @param requestCode The request code originally supplied to startActivityForResult(),
* allowing you to identify who this result came from.
* @param resultCode The integer result code returned by the child activity through its setResult().
* @param intent An Intent, which can return result data to the caller (various data can be attached to Intent "extras").
*/
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent intent) {
super.onActivityResult(requestCode, resultCode, intent);
cordovaInterface.onActivityResult(requestCode, resultCode, intent);
}
/**
* Called by the system when the user grants permissions!
*
* Note: The fragment gets priority over the activity, since the activity doesn't call
* into the parent onRequestPermissionResult, which is why there's no override.
*
* @param requestCode
* @param permissions
* @param grantResults
*/
public void onRequestPermissionsResult(int requestCode, String permissions[],
int[] grantResults) {
try
{
cordovaInterface.onRequestPermissionResult(requestCode, permissions, grantResults);
}
catch (JSONException e)
{
Log.d(TAG, "JSONException: Parameters fed into the method are not valid");
e.printStackTrace();
}
}
}
@@ -16,7 +16,7 @@
specific language governing permissions and limitations
under the License.
*/
package org.apache.cordova.test;
package org.apache.cordova.unittests;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.LOG;
@@ -1,5 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
/*
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
@@ -16,16 +15,28 @@
KIND, either express or implied. See the License for the
specific language governing permissions and limitations
under the License.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<org.apache.cordova.engine.SystemWebView
android:id="@+id/cordovaWebView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
*/
package org.apache.cordova.unittests;
</LinearLayout>
import android.os.Bundle;
import org.apache.cordova.CordovaActivity;
public class StandardActivity extends CordovaActivity {
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// enable Cordova apps to be started in the background
Bundle extras = getIntent().getExtras();
if (extras != null && extras.getBoolean("cdvStartInBackground", false)) {
moveTaskToBack(true);
}
// Set by <content src="index.html" /> in config.xml
loadUrl(launchUrl);
}
}
@@ -16,23 +16,42 @@
specific language governing permissions and limitations
under the License.
*/
package org.apache.cordova.test;
import android.content.Intent;
package org.apache.cordova.unittests;
import android.os.Bundle;
import org.apache.cordova.CordovaActivity;
import org.apache.cordova.CordovaWebView;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.RunnableFuture;
/**
* The purpose of this activity is to allow the test framework to manipulate the start url, which
* is normally locked down by CordovaActivity to standard users who aren't editing their Java code.
*/
public class TestActivity extends CordovaActivity {
public class BaseTestCordovaActivity extends CordovaActivity {
public final ArrayBlockingQueue<String> onPageFinishedUrl = new ArrayBlockingQueue<String>(500);
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// enable Cordova apps to be started in the background
Bundle extras = getIntent().getExtras();
if (extras != null) {
if (extras.getBoolean("cdvStartInBackground", false)) {
moveTaskToBack(true);
}
launchUrl = extras.getString("startUrl", "index.html");
}
// Set by <content src="index.html" /> in config.xml
loadUrl(launchUrl);
}
@Override
@@ -43,14 +62,6 @@ public class BaseTestCordovaActivity extends CordovaActivity {
return super.onMessage(id, data);
}
public CordovaWebView getCordovaWebView() {
return appView;
}
// By default, displayError shows a dialog, but for tests we just add the message to the queue
@Override
public void displayError(String title, String message, String button, boolean exit) {
onPageFinishedUrl.add(message);
}
public CordovaWebView getWebInterface() { return this.appView; }
}
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="org.apache.cordova.unittests.EmbeddedWebViewActivity">
<org.apache.cordova.engine.SystemWebView
android:id="@+id/cordovaWebView"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</RelativeLayout>
Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

@@ -0,0 +1,6 @@
<resources>
<!-- Example customization of dimensions originally defined in res/values/dimens.xml
(such as screen margins) for screens with more than 820dp of available width. This
would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->
<dimen name="activity_horizontal_margin">64dp</dimen>
</resources>
+6
View File
@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>
+5
View File
@@ -0,0 +1,5 @@
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
</resources>
+3
View File
@@ -0,0 +1,3 @@
<resources>
<string name="app_name">UnitTests</string>
</resources>
+11
View File
@@ -0,0 +1,11 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>
@@ -31,16 +31,14 @@
<access origin="https://*.googleapis.com/*" />
<access origin="https://*.gstatic.com/*" />
<content src="index.html" />
<preference name="errorUrl" value="file:///android_asset/www/htmlnotfound/error.html" />
<preference name="loglevel" value="DEBUG" />
<preference name="useBrowserHistory" value="true" />
<preference name="exit-on-suspend" value="false" />
<preference name="showTitle" value="true" />
<preference name="BackgroundColor" value="#000000" />
<feature name="Activity">
<param name="android-package" value="org.apache.cordova.test.ActivityPlugin" />
</feature>
<feature name="LifeCycle">
<param name="android-package" value="org.apache.cordova.test.LifeCyclePlugin" />
<param name="android-package" value="org.apache.cordova.unittests.LifeCyclePlugin" />
<param name="onload" value="true" />
</feature>
</widget>
@@ -0,0 +1,126 @@
package org.apache.cordova.unittests;
import android.app.Activity;
import android.content.Intent;
import android.view.View;
import android.webkit.ValueCallback;
import org.apache.cordova.CordovaInterface;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.CordovaResourceApi;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewEngine;
import org.apache.cordova.ICordovaCookieManager;
import org.apache.cordova.NativeToJsMessageQueue;
import org.apache.cordova.PluginManager;
import org.apache.cordova.PluginResult;
import org.apache.cordova.engine.SystemWebViewEngine;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.ExecutorService;
import static org.junit.Assert.*;
public class NativeToJsMessageQueueTest {
NativeToJsMessageQueue queue = new NativeToJsMessageQueue();
private String TEST_CALLBACK_ID = "MessageQueueTest";
//A queue with no bridges should not work
@Test
public void testEmptyBridge()
{
assertFalse(queue.isBridgeEnabled());
}
//A queue with at least one bridge should work, using Eval Bridge
@Test
public void testEnabledBridge()
{
NativeToJsMessageQueue.BridgeMode bridge;
bridge = new NativeToJsMessageQueue.NoOpBridgeMode();
queue.addBridgeMode(bridge);
queue.setBridgeMode(0);
assertTrue(queue.isBridgeEnabled());
}
//This test is for the undocumented encoding system setup for the bridge
//TODO: Document how the non-Javascript bridges are supposed to work
@Test
public void testPopAndEncode()
{
NativeToJsMessageQueue.BridgeMode bridge;
bridge = new NativeToJsMessageQueue.NoOpBridgeMode();
queue.addBridgeMode(bridge);
queue.setBridgeMode(0);
PluginResult result = new PluginResult(PluginResult.Status.OK);
queue.addPluginResult(result, TEST_CALLBACK_ID);
assertFalse(queue.isEmpty());
String resultString = queue.popAndEncode(false);
String [] results = resultString.split(" ");
assertEquals(TEST_CALLBACK_ID, results[2]);
}
//This test is for the evalBridge, which directly calls cordova.callbackFromNative, skipping
//platform specific NativeToJs code
@Test
public void testBasicPopAndEncodeAsJs()
{
NativeToJsMessageQueue.BridgeMode bridge;
bridge = new NativeToJsMessageQueue.NoOpBridgeMode();
queue.addBridgeMode(bridge);
queue.setBridgeMode(0);
PluginResult result = new PluginResult(PluginResult.Status.OK);
queue.addPluginResult(result, TEST_CALLBACK_ID);
assertFalse(queue.isEmpty());
String resultString = queue.popAndEncodeAsJs();
assertTrue(resultString.startsWith("cordova.callbackFromNative"));
}
//This test is for the evalBridge, which directly calls cordova.callbackFromNative, skipping
//platform specific NativeToJs code
@Test
public void testStringPopAndEncodeAsJs()
{
NativeToJsMessageQueue.BridgeMode bridge;
bridge = new NativeToJsMessageQueue.NoOpBridgeMode();
queue.addBridgeMode(bridge);
queue.setBridgeMode(0);
PluginResult result = new PluginResult(PluginResult.Status.OK, "String Plugin Result");
queue.addPluginResult(result, TEST_CALLBACK_ID);
assertFalse(queue.isEmpty());
String resultString = queue.popAndEncodeAsJs();
assertTrue(resultString.startsWith("cordova.callbackFromNative"));
}
//This test is for the evalBridge, which directly calls cordova.callbackFromNative, skipping
//platform specific NativeToJs code
@Test
public void testJsonPopAndEncodeAsJs()
{
NativeToJsMessageQueue.BridgeMode bridge;
bridge = new NativeToJsMessageQueue.NoOpBridgeMode();
queue.addBridgeMode(bridge);
queue.setBridgeMode(0);
JSONObject object = new JSONObject();
try {
object.put("test", "value");
} catch (JSONException e) {
e.printStackTrace();
}
PluginResult result = new PluginResult(PluginResult.Status.OK, object);
queue.addPluginResult(result, TEST_CALLBACK_ID);
assertFalse(queue.isEmpty());
String resultString = queue.popAndEncodeAsJs();
assertTrue(resultString.startsWith("cordova.callbackFromNative"));
}
}
-103
View File
@@ -1,103 +0,0 @@
<!DOCTYPE HTML>
<!--
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>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Background Page 1</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">
function onLoad() {
console.log("Page1: onload");
log("Page1: onload @ " + new Date().toLocaleTimeString());
document.addEventListener("deviceready", onDeviceReady, false);
}
function onUnLoaded() {
console.log("Page1: onunload");
log("Page1: onunload @ " + new Date().toLocaleTimeString());
}
function onDeviceReady() {
// Register the event listener
document.getElementById("deviceready").innerHTML = "fired";
document.getElementById("cordova").innerHTML = cordova.version;
document.addEventListener("pause", onPause, false);
document.addEventListener("resume", onResume, false);
window.setInterval(function() {
log("Page1: Running");
}, 2000);
}
function onPause() {
console.log("Page1: onpause");
log("Page1: onpause @ " + new Date().toLocaleTimeString());
}
function onResume() {
console.log("Page1: onresume");
log("Page1: onresume @ " + new Date().toLocaleTimeString());
}
function log(s) {
var el = document.getElementById('status');
var status = el.innerHTML + s + "<br>";
el.innerHTML = status;
localStorage.backgroundstatus = status;
}
function clearStatus() {
console.log("clear()");
localStorage.backgroundstatus = "";
document.getElementById('status').innerHTML = "";
}
</script>
</head>
<body onload="onLoad()" onunload="onUnLoaded()" id="stage" class="theme">
<h1>Events</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>
</div>
<div id="info">
Press "Home" button, then return to this app to see pause/resume.<br>
There shouldn't be any "Running" entries between pause and resume.<br>
</div>
<div id="info">
<h4>Info for event testing:</h4>
<div id="status"></div>
</div>
<!-- a href="index2.html" class="btn large" >Load new page</a -->
<a href="javascript:" class="btn large" onclick="clearStatus();">Clear status</a>
<script>
document.getElementById('status').innerHTML = localStorage.backgroundstatus;
</script>
</body>
</html>
-102
View File
@@ -1,102 +0,0 @@
<!DOCTYPE HTML>
<!--
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>
<head>
<meta http-equiv="Content-type" content="text/html; charset=utf-8">
<title>Background Page 2</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">
function onLoad() {
console.log("Page2: onload");
log("Page2: onload @ " + new Date().toLocaleTimeString());
document.addEventListener("deviceready", onDeviceReady, false);
}
function onUnLoaded() {
console.log("Page2: onunload");
log("Page2: onunload @ " + new Date().toLocaleTimeString());
}
function onDeviceReady() {
// Register the event listener
document.getElementById("deviceready").innerHTML = "fired";
document.getElementById("cordova").innerHTML = cordova.version;
document.addEventListener("pause", onPause, false);
document.addEventListener("resume", onResume, false);
window.setInterval(function() {
log("Page2: Running");
}, 2000);
}
function onPause() {
console.log("Page2: onpause");
log("Page2: onpause @ " + new Date().toLocaleTimeString());
}
function onResume() {
console.log("Page2: onresume");
log("Page2: onresume @ " + new Date().toLocaleTimeString());
}
function log(s) {
var el = document.getElementById('status');
var status = el.innerHTML + s + "<br>";
el.innerHTML = status;
localStorage.backgroundstatus = status;
}
function clearStatus() {
console.log("clear()");
localStorage.backgroundstatus = "";
document.getElementById('status').innerHTML = "";
}
</script>
</head>
<body onload="onLoad()" onunload="onUnLoaded()" id="stage" class="theme">
<h1>Events</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>
</div>
<div id="info">
<h4>Press "Back" button to return to Page 1.</h4>
</div>
<div id="info">
<h4>Info for event testing:</h4>
<div id="status"></div>
</div>
<a href="index.html" class="btn large" >Load new page</a>
<a href="javascript:" class="btn large" onclick="clearStatus();">Clear status</a>
<script>
document.getElementById('status').innerHTML = localStorage.backgroundstatus;
</script>
</body>
</html>
-40
View File
@@ -1,40 +0,0 @@
<!--
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>Basic Auth</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>
</div>
<div id="info">
Loading link below should be successful and show page indicating username=test & password=test. <br>
</div>
<a href="http://browserspy.dk/password-ok.php" class="btn large">Test password</a>
</body>
</html>
@@ -1,67 +0,0 @@
<!--
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="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.css" />
<script src="http://code.jquery.com/jquery-1.7.1.min.js"></script>
<script src="http://code.jquery.com/mobile/1.0.1/jquery.mobile-1.0.1.min.js"></script>
<script type="text/javascript" src="../cordova.js"></script>
<script>
document.addEventListener("deviceready", onDeviceReady, false);
// Without backbutton handler, each tab loaded will be popped off history until history is empty, then it will exit app.
function handleBackButton() {
alert("Back Button Pressed! - exiting app");
navigator.app.exitApp();
}
function onDeviceReady() {
console.log("onDeviceReady()");
document.addEventListener("backbutton", handleBackButton, false);
}
</script>
</head>
<body>
<div data-role="page" id="tabTab">
<div data-role="header">
<h1>Main</h1>
</div>
<div data-role="content" id="tabContent">
To test, press several tabs.<br>
The "backbutton" can be pressed any time to exit app.
</div>
<div data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li><a href="tab1.html" data-transition="none">Tab 1</a>
</li>
<li><a href="tab2.html" data-transition="none">Tab 2</a>
</li>
<li><a href="tab3.html" data-transition="none">Tab 3</a>
</li>
</ul>
</div>
</div>
</div>
@@ -1,47 +0,0 @@
<!--
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>Tab 1</title>
</head>
<body>
<div data-role="page" id="tab1Tab">
<div data-role="header">
<h1>Tab 1</h1>
</div>
<div data-role="content" id="tab1Content">
Tab 1 content.
</div>
<div data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li><a href="tab1.html" data-transition="none">Tab 1</a>
</li>
<li><a href="tab2.html" data-transition="none">Tab 2</a>
</li>
<li><a href="tab3.html" data-transition="none">Tab 3</a>
</li>
</ul>
</div>
<!-- /navbar -->
</div>
<!-- /footer -->
</div>
@@ -1,48 +0,0 @@
<!--
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>Tab 2</title>
</head>
<body>
<div data-role="page" id="tab2Tab">
<div data-role="header">
<h1>Tab 2</h1>
</div>
<div data-role="content" id="tab2Content">
Tab 2 content.
</div>
<div data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li><a href="tab1.html" data-transition="none">Tab 1</a>
</li>
<li><a href="tab2.html" data-transition="none">Tab 2</a>
</li>
<li><a href="tab3.html" data-transition="none">Tab 3</a>
</li>
</ul>
</div>
<!-- /navbar -->
</div>
<!-- /footer -->
</div>
@@ -1,48 +0,0 @@
<!--
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>Tab 3</title>
</head>
<body>
<div data-role="page" id="tab3Tab">
<div data-role="header">
<h1>Tab 3</h1>
</div>
<div data-role="content" id="tab3Content">
Tab 3 content.
</div>
<div data-role="footer" data-position="fixed">
<div data-role="navbar">
<ul>
<li><a href="tab1.html" data-transition="none">Tab 1</a>
</li>
<li><a href="tab2.html" data-transition="none">Tab 2</a>
</li>
<li><a href="tab3.html" data-transition="none">Tab 3</a>
</li>
</ul>
</div>
<!-- /navbar -->
</div>
<!-- /footer -->
</div>
-45
View File
@@ -1,45 +0,0 @@
<!DOCTYPE HTML>
<!--
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 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>Menu Test</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>
</div>
<div id="info">
<h4>The options menu items should be:</h4>
<li>Item1<br>
<li>Item2<br>
<li>Item3<br>
<h4>There is also a context menu. Touch and hold finger here to see:</h4>
<li>Context Item1<br>
</div>
</body>
</html>
-65
View File
@@ -1,65 +0,0 @@
<!--
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>User WebView/Client/Chrome Test</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>
</div>
<div id="info">
<h4>The following should be seen in LogCat:</h4>
<li>userwebview: TestViewClient()<br>
<li>userwebview: TestChromeClient()<br>
<li>userwebview: onGeolocationPermissionsShowPrompt(file://)<br>
<li>userwebview: shouldOverrideUrlLoading(test://this_will_call_shouldOverrideUrlLoading)<br>
</div>
<script>
/**
* Get current location
*/
console.log("getLocation()");
// Success callback
var success = function(p){
console.log("Location = "+p.coords.latitude+","+p.coords.longitude);
window.location = "test://this_will_call_shouldOverrideUrlLoading";
};
// Fail callback
var fail = function(e){
console.log("Error: "+e.code);
};
// Get location
navigator.geolocation.getCurrentPosition(success, fail, {enableHighAccuracy: true});
</script>
</body>
</html>
-64
View File
@@ -1,64 +0,0 @@
<!--
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>
<script>
function XHR(url) {
var xmlhttp = new XMLHttpRequest();
xmlhttp.onreadystatechange=function(){
if(xmlhttp.readyState === 4){
// If success
if (xmlhttp.status === 200) {
alert("XHR success. Result="+xmlhttp.responseText);
}
// If error
else {
alert("XHR error. Status="+xmlhttp.status);
}
}
};
console.log("GET "+url);
xmlhttp.open("GET", url , true);
xmlhttp.send();
}
</script>
</head>
<body onload="init();" id="stage" class="theme">
<h1>XHR</h1>
<div id="info">
<h4>Cordova: <span id="cordova"> &nbsp;</span></h4>
<h4>Deviceready: <span id="deviceready"> &nbsp;</span></h4>
</div>
<div id="info">
Press buttons below to test. You should see an alert with results displayed.
</div>
<a href="javascript:" class="btn large" onclick="XHR('file:///android_asset/www/xhr/index.html')">Load file://</a>
<a href="javascript:" class="btn large" onclick="XHR('http://www.google.com');">Load Google</a>
<!--
<a href="javascript:" class="btn large" onclick="XHR('content://com.android.contacts/data/1');">Load content://</a>
-->
</body>
</html>
+7 -76
View File
@@ -1,31 +1,14 @@
/*
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.
*/
apply plugin: 'android'
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.2.1'
classpath 'com.android.tools.build:gradle:2.2.3'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
@@ -35,58 +18,6 @@ allprojects {
}
}
ext {
apply from: '../framework/cordova.gradle'
cdvCompileSdkVersion = privateHelpers.getProjectTarget()
cdvBuildToolsVersion = privateHelpers.findLatestInstalledBuildTools()
task clean(type: Delete) {
delete rootProject.buildDir
}
android {
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest {
java.srcDirs = ['androidTest/src']
resources.srcDirs = ['androidTest/src']
res.srcDirs = []
assets.srcDirs = []
}
}
defaultConfig {
testInstrumentationRunner "android.test.InstrumentationTestRunner"
}
testOptions {
unitTests.returnDefaultValues = true
}
compileSdkVersion cdvCompileSdkVersion
buildToolsVersion cdvBuildToolsVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_6
targetCompatibility JavaVersion.VERSION_1_6
}
}
dependencies {
debugCompile project(path: ":CordovaLib", configuration: "debug")
releaseCompile project(path: ":CordovaLib", configuration: "release")
androidTestCompile fileTree(dir: 'androidTest/libs', include: '*.jar')
testCompile 'junit:junit:4.12'
}
task copyCordovaJs (type: Copy) {
from '../bin/templates/project/assets/www'
into 'assets/www'
include('cordova.js')
}
preBuild.dependsOn copyCordovaJs
+17
View File
@@ -0,0 +1,17 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
+6
View File
@@ -0,0 +1,6 @@
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
Vendored Executable
+160
View File
@@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
+90
View File
@@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
-12
View File
@@ -1,12 +0,0 @@
# This file is automatically generated by Android Tools.
# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
#
# This file must be checked in Version Control Systems.
#
# To customize properties used by the Ant build system use,
# "ant.properties", and override values to adapt the script to your
# project structure.
# Project target.
target=android-21
android.library.reference.1=../framework
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.7 KiB

-22
View File
@@ -1,22 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
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.
-->
<resources>
<string name="app_name">CordovaNativeTests</string>
</resources>
+1 -20
View File
@@ -1,22 +1,3 @@
/* 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.
*/
include ":"
include ':app'
include ":CordovaLib"
project(':CordovaLib').projectDir = new File('../framework')
@@ -1,73 +0,0 @@
/*
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.test;
import org.apache.cordova.CordovaArgs;
import org.apache.cordova.LOG;
import org.json.JSONArray;
import org.json.JSONException;
import android.content.Intent;
import org.apache.cordova.CallbackContext;
import org.apache.cordova.CordovaPlugin;
import org.apache.cordova.PluginResult;
import org.json.JSONObject;
import java.util.Collections;
import java.util.Iterator;
public class ActivityPlugin extends CordovaPlugin {
static String TAG = "ActivityPlugin";
public static final String BACKBUTTONMULTIPAGE_URL = "file:///android_asset/www/backbuttonmultipage/index.html";
public boolean execute(String action, CordovaArgs args, final CallbackContext callbackContext) throws JSONException {
if (action.equals("start")) {
String className = args.isNull(0) ? MainTestActivity.class.getCanonicalName() : args.getString(0);
String startUrl = args.getString(1);
JSONObject extraPrefs = args.getJSONObject(2);
this.startActivity(className, startUrl, extraPrefs);
callbackContext.success();
return true;
}
return false;
}
public void startActivity(String className, String startUrl, JSONObject extraPrefs) throws JSONException {
try {
if (!startUrl.contains(":")) {
startUrl = "file:///android_asset/www/" + startUrl;
}
Intent intent = new Intent(this.cordova.getActivity(), Class.forName(className));
intent.putExtra("testStartUrl", startUrl);
Iterator<String> iter = extraPrefs.keys();
while (iter.hasNext()) {
String key = iter.next();
intent.putExtra(key, extraPrefs.getString(key));
}
LOG.d(TAG, "Starting activity %s", className);
this.cordova.getActivity().startActivity(intent);
} catch (ClassNotFoundException e) {
e.printStackTrace();
LOG.e(TAG, "Error starting activity %s", className);
}
}
}
@@ -1,74 +0,0 @@
/*
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.test;
import java.util.concurrent.ArrayBlockingQueue;
import org.apache.cordova.Config;
import org.apache.cordova.ConfigXmlParser;
import org.apache.cordova.CordovaInterfaceImpl;
import org.apache.cordova.CordovaWebView;
import org.apache.cordova.CordovaWebViewImpl;
import org.apache.cordova.engine.SystemWebView;
import org.apache.cordova.engine.SystemWebViewEngine;
import android.app.Activity;
import android.os.Bundle;
/**
* Tests creating the views via inflating a layout, and also tests *not* using CordovaActivity.
*/
public class CordovaWebViewTestActivity extends Activity {
private CordovaWebView cordovaWebView;
public final ArrayBlockingQueue<String> onPageFinishedUrl = new ArrayBlockingQueue<String>(5);
public static final String START_URL = "file:///android_asset/www/index.html";
protected CordovaInterfaceImpl cordovaInterface = new CordovaInterfaceImpl(this) {
@Override
public Object onMessage(String id, Object data) {
if ("onPageFinished".equals(id)) {
onPageFinishedUrl.add((String) data);
}
return super.onMessage(id, data);
}
};
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
//Set up the webview
ConfigXmlParser parser = new ConfigXmlParser();
parser.parse(this);
SystemWebView webView = (SystemWebView) findViewById(R.id.cordovaWebView);
cordovaWebView = new CordovaWebViewImpl(new SystemWebViewEngine(webView));
cordovaWebView.init(cordovaInterface, parser.getPluginEntries(), parser.getPreferences());
cordovaWebView.loadUrl(START_URL);
}
public CordovaWebView getCordovaWebView() {
return cordovaWebView;
}
}
@@ -1,45 +0,0 @@
/*
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.test;
import android.os.Bundle;
public class MainTestActivity extends BaseTestCordovaActivity {
public static final String START_URL = "file:///android_asset/www/index.html";
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String url = getIntent().getStringExtra("testStartUrl");
if (url == null) {
url = START_URL;
}
super.loadUrl(url);
}
@Override protected void loadConfig() {
super.loadConfig();
// Need to set this explicitly in prefs since it's not settable via bundle extras.
String errorUrl = getIntent().getStringExtra("testErrorUrl");
if (errorUrl != null) {
preferences.set("errorUrl", errorUrl);
}
}
}

Some files were not shown because too many files have changed in this diff Show More