Compare commits

..

6 Commits

Author SHA1 Message Date
Ken Naito
1c9e7fc96a fix: backbutton test code (#1307) 2021-08-02 20:25:04 +09:00
Erisu
5e52b7ee77 fix: logging method 2021-08-02 15:15:27 +09:00
Erisu
f3e98c8651 refactor: rename java_unit_tests command & test runner file 2021-08-02 14:30:25 +09:00
Erisu
bbc9bcae14 refactor: java test runner 2021-08-02 14:30:25 +09:00
Erisu
cd49902ca3 fix: add androidx.test:rules library 2021-08-02 14:30:25 +09:00
Erisu
f4a0e1ec78 ci: add Java instrumentation tests 2021-08-02 14:30:25 +09:00
14 changed files with 92 additions and 94 deletions

View File

@@ -28,44 +28,22 @@
Cordova Android is an Android application library that allows for Cordova-based projects to be built for the Android Platform. Cordova based applications are, at the core, applications written with web technology: HTML, CSS and JavaScript.
[Apache Cordova](https://cordova.apache.org/) is a project of [The Apache Software Foundation (ASF)](https://apache.org/).
[Apache Cordova](https://cordova.apache.org) is a project of The Apache Software Foundation (ASF).
## Requirements
* Java Development Kit (JDK) 11
* [Android SDK](https://developer.android.com/)
* [Node.js](https://nodejs.org)
- Java Development Kit (JDK) 11
- [Android SDK](https://developer.android.com/)
## Create a Cordova project
## Cordova Android Developer Tools
Follow the instructions in the [**Create your first Cordova app**](https://cordova.apache.org/docs/en/latest/guide/cli/index.html) section of [Apache Cordova Docs](https://cordova.apache.org/docs/en/latest/)
Use the [Cordova command-line tool](https://www.npmjs.com/package/cordova) to create projects and install plugins.
To use a **shared framework**, for example in development, link the appropriate cordova-android platform folder path:
## Using Android Studio
```bash
cordova platform add --link /path/to/cordova-android
```
1. Create a project
2. Import it via "Non-Android Studio Project"
## Updating a Cordova project
## Running the Native Tests
When you install a new version of the [`Cordova CLI`](https://www.npmjs.com/package/cordova) that pins a new version of the [`Cordova-Android`](https://www.npmjs.com/package/cordova-android) platform, you can follow these simple upgrade steps within your project:
```bash
cordova platform rm android
cordova platform add android
```
## Debugging in Android Studio
Import project in Android Studio through _File > Open_ and targeting `/path/to/your-cdv-project/platforms/android/`.
## How to Test Repo Development
```bash
npm install
npm test
```
## Further reading
* [Apache Cordova](https://cordova.apache.org/)
The `test/` directory in this project contains an Android test project that can be used to run different kinds of native tests. Check out the [README contained therein](test/README.md) for more details!

View File

@@ -20,25 +20,6 @@
-->
## Release Notes for Cordova (Android)
### 10.1.0 (Aug 13, 2021)
**Features:**
* [GH-1213](https://github.com/apache/cordova-android/pull/1213) feat: unify `create` default values & stop project name transform
* [GH-1306](https://github.com/apache/cordova-android/pull/1306) feat: bump `ANDROIDX_APP_COMPAT@1.3.1`
* [GH-1303](https://github.com/apache/cordova-android/pull/1303) feat: bump `Google Services Gradle Plugin@4.3.8`
* [GH-1302](https://github.com/apache/cordova-android/pull/1302) feat: bump `kotlin@1.5.21`
* [GH-1298](https://github.com/apache/cordova-android/pull/1298) feat: support `http` w/ `content` `src` fix
**Fixes:**
* [GH-1214](https://github.com/apache/cordova-android/pull/1214) fix: display project name in Android Studio
* [GH-1300](https://github.com/apache/cordova-android/pull/1300) fix: fall back to project root `repositories.gradle`
**Docs:**
* [GH-1308](https://github.com/apache/cordova-android/pull/1308) doc: update `README` about development & testing
### 10.0.1 (Jul 27, 2021)
**Fixes:**

View File

@@ -5,7 +5,7 @@
"MIN_BUILD_TOOLS_VERSION": "30.0.3",
"AGP_VERSION": "4.2.2",
"KOTLIN_VERSION": "1.5.21",
"ANDROIDX_APP_COMPAT_VERSION": "1.3.1",
"ANDROIDX_APP_COMPAT_VERSION": "1.3.0",
"ANDROIDX_WEBKIT_VERSION": "1.4.0",
"GRADLE_PLUGIN_GOOGLE_SERVICES_VERSION": "4.3.8",
"IS_GRADLE_PLUGIN_GOOGLE_SERVICES_ENABLED": false,

View File

@@ -31,7 +31,7 @@ import android.webkit.WebChromeClient.CustomViewCallback;
* are not expected to implement it.
*/
public interface CordovaWebView {
public static final String CORDOVA_VERSION = "10.1.0";
public static final String CORDOVA_VERSION = "10.1.0-dev";
void init(CordovaInterface cordova, List<PluginEntry> pluginEntries, CordovaPreferences preferences);

View File

@@ -183,29 +183,21 @@ class ProjectBuilder {
checkAndCopy(subProjects[i], this.root);
}
}
var projectName = this.extractRealProjectNameFromManifest();
var name = this.extractRealProjectNameFromManifest();
// Remove the proj.id/name- prefix from projects: https://issues.apache.org/jira/browse/CB-9149
var settingsGradlePaths = subProjects.map(function (p) {
var realDir = p.replace(/[/\\]/g, ':');
var libName = realDir.replace(projectName + '-', '');
var libName = realDir.replace(name + '-', '');
var str = 'include ":' + libName + '"\n';
if (realDir.indexOf(projectName + '-') !== -1) {
if (realDir.indexOf(name + '-') !== -1) {
str += 'project(":' + libName + '").projectDir = new File("' + p + '")\n';
}
return str;
});
// Update subprojects within settings.gradle.
fs.writeFileSync(path.join(this.root, 'settings.gradle'),
'// GENERATED FILE - DO NOT EDIT\n' +
'apply from: "cdv-gradle-name.gradle"\n' +
'include ":"\n' +
settingsGradlePaths.join(''));
// Touch empty cdv-gradle-name.gradle file if missing.
if (!fs.pathExistsSync(path.join(this.root, 'cdv-gradle-name.gradle'))) {
fs.writeFileSync(path.join(this.root, 'cdv-gradle-name.gradle'), '');
}
'include ":"\n' + settingsGradlePaths.join(''));
// Update dependencies within build.gradle.
var buildGradle = fs.readFileSync(path.join(this.root, 'app', 'build.gradle'), 'utf8');
@@ -222,7 +214,7 @@ class ProjectBuilder {
};
subProjects.forEach(function (p) {
events.emit('log', 'Subproject Path: ' + p);
var libName = p.replace(/[/\\]/g, ':').replace(projectName + '-', '');
var libName = p.replace(/[/\\]/g, ':').replace(name + '-', '');
if (libName !== 'app') {
depsList += ' implementation(project(path: ":' + libName + '"))';
insertExclude(p);

View File

@@ -37,6 +37,7 @@ exports.copyScripts = copyScripts;
exports.copyBuildRules = copyBuildRules;
exports.writeProjectProperties = writeProjectProperties;
exports.prepBuildFiles = prepBuildFiles;
exports.writeNameForAndroidStudio = writeNameForAndroidStudio;
function getFrameworkDir (projectPath, shared) {
return shared ? path.join(ROOT, 'framework') : path.join(projectPath, 'CordovaLib');
@@ -175,6 +176,19 @@ function validateProjectName (project_name) {
return Promise.resolve();
}
/**
* Write the name of the app in "platforms/android/.idea/.name" so that Android Studio can show that name in the
* project listing. This is helpful to quickly look in the Android Studio listing if there are so many projects in
* Android Studio.
*
* https://github.com/apache/cordova-android/issues/1172
*/
function writeNameForAndroidStudio (project_path, project_name) {
const ideaPath = path.join(project_path, '.idea');
fs.ensureDirSync(ideaPath);
fs.writeFileSync(path.join(ideaPath, '.name'), project_name);
}
/**
* Creates an android application with the given options.
*
@@ -197,14 +211,15 @@ exports.create = function (project_path, config, options, events) {
options = options || {};
// Set default values for path, package and name
project_path = path.relative(process.cwd(), project_path);
project_path = path.relative(process.cwd(), (project_path || 'CordovaExample'));
// Check if project already exists
if (fs.existsSync(project_path)) {
return Promise.reject(new CordovaError('Project already exists! Delete and recreate'));
}
var package_name = config.android_packageName() || config.packageName() || 'io.cordova.helloCordova';
var project_name = config.name() || 'Hello Cordova';
var package_name = config.android_packageName() || config.packageName() || 'my.cordova.project';
var project_name = config.name()
? config.name().replace(/[^\w.]/g, '_') : 'CordovaExample';
var safe_activity_name = config.android_activityName() || options.activityName || 'MainActivity';
var target_api = check_reqs.get_target(project_path);
@@ -214,7 +229,7 @@ exports.create = function (project_path, config, options, events) {
.then(function () {
return exports.validateProjectName(project_name);
}).then(function () {
// Log the given values for the project
// Log the given values for the project
events.emit('log', 'Creating Cordova project for the Android platform:');
events.emit('log', '\tPath: ' + project_path);
events.emit('log', '\tPackage: ' + package_name);
@@ -271,6 +286,7 @@ exports.create = function (project_path, config, options, events) {
// Link it to local android install.
exports.writeProjectProperties(project_path, target_api);
exports.prepBuildFiles(project_path);
exports.writeNameForAndroidStudio(project_path, project_name);
events.emit('log', generateDoneMessage('create', options.link));
}).then(() => project_path);
};

View File

@@ -273,11 +273,6 @@ function updateProjectAccordingTo (platformConfig, locations) {
fs.writeFileSync(locations.strings, strings.write({ indent: 4 }), 'utf-8');
events.emit('verbose', 'Wrote out android application name "' + name + '" to ' + locations.strings);
// Update app name for gradle project
fs.writeFileSync(path.join(locations.root, 'cdv-gradle-name.gradle'),
'// GENERATED FILE - DO NOT EDIT\n' +
'rootProject.name = "' + name.replace(/[/\\:<>"?*|]/g, '_') + '"\n');
// Java packages cannot support dashes
var androidPkgName = (platformConfig.android_packageName() || platformConfig.packageName()).replace(/-/g, '_');

2
package-lock.json generated
View File

@@ -1,6 +1,6 @@
{
"name": "cordova-android",
"version": "10.1.0",
"version": "10.1.0-dev",
"lockfileVersion": 1,
"requires": true,
"dependencies": {

View File

@@ -1,6 +1,6 @@
{
"name": "cordova-android",
"version": "10.1.0",
"version": "10.1.0-dev",
"description": "cordova-android release",
"main": "lib/Api.js",
"repository": "github:apache/cordova-android",
@@ -12,13 +12,13 @@
],
"scripts": {
"prepare": "cordova-js build > templates/project/assets/www/cordova.js",
"test": "npm run lint && npm run cover && npm run java-unit-tests",
"test": "npm run lint && npm run cover && npm run java-tests",
"lint": "eslint lib spec test \"templates/cordova/**/!(*.*)\"",
"unit-tests": "jasmine --config=spec/unit/jasmine.json",
"cover": "nyc jasmine --config=spec/coverage.json",
"e2e-tests": "jasmine --config=spec/e2e/jasmine.json",
"java-unit-tests": "node test/run_java_unit_tests.js",
"clean:java-unit-tests": "node test/clean.js"
"java-tests": "node test/java_test_runner.js",
"clean:java-tests": "node test/clean.js"
},
"author": "Apache Software Foundation",
"license": "Apache-2.0",

View File

@@ -132,6 +132,7 @@ describe('create', function () {
spyOn(create, 'copyBuildRules');
spyOn(create, 'writeProjectProperties');
spyOn(create, 'prepBuildFiles');
spyOn(create, 'writeNameForAndroidStudio');
revert_manifest_mock = create.__set__('AndroidManifest', Manifest_mock);
spyOn(fs, 'existsSync').and.returnValue(false);
spyOn(fs, 'copySync');
@@ -147,10 +148,10 @@ describe('create', function () {
});
describe('parameter values and defaults', function () {
it('should have a default package name of io.cordova.helloCordova', () => {
it('should have a default package name of my.cordova.project', () => {
config_mock.packageName.and.returnValue(undefined);
return create.create(project_path, config_mock, {}, events_mock).then(() => {
expect(create.validatePackageName).toHaveBeenCalledWith('io.cordova.helloCordova');
expect(create.validatePackageName).toHaveBeenCalledWith('my.cordova.project');
});
});
@@ -161,10 +162,10 @@ describe('create', function () {
});
});
it('should have a default project name of Hello Cordova', () => {
it('should have a default project name of CordovaExample', () => {
config_mock.name.and.returnValue(undefined);
return create.create(project_path, config_mock, {}, events_mock).then(() => {
expect(create.validateProjectName).toHaveBeenCalledWith('Hello Cordova');
expect(create.validateProjectName).toHaveBeenCalledWith('CordovaExample');
});
});
@@ -175,10 +176,10 @@ describe('create', function () {
});
});
it('should keep non-word characters (including unicode and spaces) in the ConfigParser-provided project name', () => {
it('should replace any non-word characters (including unicode and spaces) in the ConfigParser-provided project name with underscores', () => {
config_mock.name.and.returnValue('応応応応 hello 用用用用');
return create.create(project_path, config_mock, {}, events_mock).then(() => {
expect(create.validateProjectName).toHaveBeenCalledWith('応応応応 hello 用用用用');
expect(create.validateProjectName).toHaveBeenCalledWith('_____hello_____');
});
});
@@ -300,4 +301,24 @@ describe('create', function () {
});
});
});
describe('writeNameForAndroidStudio', () => {
const project_path = path.join('some', 'path');
const appName = 'Test Cordova';
beforeEach(function () {
spyOn(fs, 'ensureDirSync');
spyOn(fs, 'writeFileSync');
});
it('should call ensureDirSync with path', () => {
create.writeNameForAndroidStudio(project_path, appName);
expect(fs.ensureDirSync).toHaveBeenCalledWith(path.join(project_path, '.idea'));
});
it('should call writeFileSync with content', () => {
create.writeNameForAndroidStudio(project_path, appName);
expect(fs.writeFileSync).toHaveBeenCalledWith(path.join(project_path, '.idea', '.name'), appName);
});
});
});

View File

@@ -56,6 +56,8 @@ dependencies {
androidTestImplementation('androidx.test.espresso:espresso-web:3.1.1', {
exclude group: 'androidx.test.espresso', module: 'androidx.annotation'
})
androidTestImplementation 'androidx.test:rules:1.4.0'
}
repositories {
google()

View File

@@ -158,7 +158,7 @@ public class BackButtonMultipageTest {
assertEquals(START_URL, mActivity.onPageFinishedUrl.take());
}
private void assertPageSample(String url) {
private void assertPageSample(String url) throws Throwable {
assertEquals(url, mActivity.onPageFinishedUrl.take());
}
}

View File

@@ -21,7 +21,7 @@ const fs = require('fs-extra');
const path = require('path');
/**
* This script is to be run manually (e.g. by npm run clean:java-unit-tests) if
* This script is to be run manually (e.g. by npm run clean:java-tests) if
* you want to upgrade gradlew or test its proper generation.
*/

View File

@@ -46,9 +46,13 @@ class AndroidTestRunner {
return new ProjectBuilder(this.projectDir).runGradleWrapper('gradle');
}
_log (...args) {
console.log(...[`[${this.testTitle}]`, ...args]);
}
run () {
return Promise.resolve()
.then(_ => console.log(`[${this.testTitle}] Preparing Gradle wrapper for Java unit tests.`))
.then(_ => this._log('Staging Project Files'))
.then(_ => {
// TODO we should probably not only copy these files, but instead create a new project from scratch
fs.copyFileSync(path.resolve(this.projectDir, '../../framework/cdv-gradle-config-defaults.json'), path.resolve(this.projectDir, 'cdv-gradle-config.json'));
@@ -57,26 +61,35 @@ class AndroidTestRunner {
path.join(this.projectDir, 'app/src/main/assets/www/cordova.js')
);
})
.then(_ => this._log('Creating Gradle Wrapper'))
.then(_ => this._createProjectBuilder())
.then(_ => this._log('Getting Gradle Wrapper Version Info'))
.then(_ => this._gradlew('--version'))
.then(_ => console.log(`[${this.testTitle}] Gradle wrapper is ready. Running tests now.`))
.then(_ => this._log('Running Java Unit Tests'))
.then(_ => this._gradlew('test'))
.then(_ => console.log(`[${this.testTitle}] Java unit tests completed successfully`));
.then(_ => this._log('Finished Java Unit Test'))
.then(_ => this._log('Running Java Instrumentation Tests'))
.then(_ => this._gradlew('connectedAndroidTest'))
.then(_ => this._log('Finished Java Instrumentation Tests'));
}
}
Promise.resolve()
.then(_ => console.log('Starting to run all android platform tests'))
.then(_ => console.log('Starting Android Platform Java Tests'))
// AndroidX Test
.then(_ => new AndroidTestRunner('AndroidX Project', path.resolve(__dirname, 'androidx')))
.then(test => test.run())
.then(_ => console.log('Finished running all android platform tests'));
.then(_ => console.log('Finished Running Android Platform Java Tests'));
process.on('unhandledRejection', err => {
// If err has a stderr property, we have seen the message already
if (!('stderr' in err)) console.error(err.message);
console.error('JAVA UNIT TESTS FAILED!');
console.error('JAVA TESTS FAILED!');
process.exitCode = err.code || 1;
});