From 32edaee3a248b0c10ae3d57003636a9b82dfec9c Mon Sep 17 00:00:00 2001 From: Alexander Sorokin Date: Mon, 2 Nov 2015 18:58:13 +0300 Subject: [PATCH] CB-9831 CB-9835 CB-9932 Added e2e tests --- .travis.yml | 4 +- package.json | 4 +- spec/{ => create}/create.spec.js | 2 +- spec/e2e/create.spec.js | 80 ++++++++++ .../android/FakeLib/project.properties | 15 ++ .../fixtures/cordova-plugin-fake/plugin.xml | 44 +++++ spec/e2e/helpers/projectActions.js | 151 ++++++++++++++++++ spec/e2e/plugin.spec.js | 44 +++++ spec/e2e/update.spec.js | 97 +++++++++++ 9 files changed, 435 insertions(+), 6 deletions(-) rename spec/{ => create}/create.spec.js (98%) create mode 100644 spec/e2e/create.spec.js create mode 100644 spec/e2e/fixtures/cordova-plugin-fake/platforms/android/FakeLib/project.properties create mode 100644 spec/e2e/fixtures/cordova-plugin-fake/plugin.xml create mode 100644 spec/e2e/helpers/projectActions.js create mode 100644 spec/e2e/plugin.spec.js create mode 100644 spec/e2e/update.spec.js diff --git a/.travis.yml b/.travis.yml index cbc8d681..88f8cccf 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,10 +1,8 @@ language: android sudo: false install: - - "(pushd .. && git clone https://github.com/apache/cordova-lib.git && popd)" - - npm link ../cordova-lib/cordova-common - npm install - - echo y | android update sdk -u --filter android-23 + - echo y | android update sdk -u --filter android-22,android-23 script: - npm test - npm run test-build diff --git a/package.json b/package.json index 25a83e5d..df1c63bc 100644 --- a/package.json +++ b/package.json @@ -16,8 +16,8 @@ "apache" ], "scripts": { - "test": "npm run jshint && jasmine-node --color spec", - "test-build": "rm -rf \"test create\" && node ./bin/create \"test create\" com.test.app 応用 && \"./test create/cordova/build\" && rm -rf \"test create\"", + "test": "npm run jshint && jasmine-node --color spec/create", + "test-build": "jasmine-node --captureExceptions --color spec/e2e", "jshint": "node node_modules/jshint/bin/jshint bin && node node_modules/jshint/bin/jshint spec" }, "author": "Apache Software Foundation", diff --git a/spec/create.spec.js b/spec/create/create.spec.js similarity index 98% rename from spec/create.spec.js rename to spec/create/create.spec.js index 840c4f14..2a1038e8 100644 --- a/spec/create.spec.js +++ b/spec/create/create.spec.js @@ -20,7 +20,7 @@ require("promise-matchers"); -var create = require("../bin/lib/create"); +var create = require("../../bin/lib/create"); describe("create", function () { describe("validatePackageName", function() { diff --git a/spec/e2e/create.spec.js b/spec/e2e/create.spec.js new file mode 100644 index 00000000..805378de --- /dev/null +++ b/spec/e2e/create.spec.js @@ -0,0 +1,80 @@ +/* + 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. + */ + +var actions = require('./helpers/projectActions.js'); + +var CREATE_TIMEOUT = 60000; + +function createAndBuild(projectname, projectid, done) { + actions.createProject(projectname, projectid, function (error) { + expect(error).toBe(null); + actions.buildProject(projectid, function (error) { + expect(error).toBe(null); + actions.removeProject(projectid); + done(); + }); + }); +} + + +describe('create', function() { + + it('create project with ascii name, no spaces', function(done) { + var projectname = 'testcreate'; + var projectid = 'com.test.create.app1'; + + createAndBuild(projectname, projectid, done); + }, CREATE_TIMEOUT); + + it('create project with ascii name, and spaces', function(done) { + var projectname = 'test create'; + var projectid = 'com.test.create.app2'; + + createAndBuild(projectname, projectid, done); + }, CREATE_TIMEOUT); + + it('create project with unicode name, no spaces', function(done) { + var projectname = '応応応応用用用用'; + var projectid = 'com.test.create.app3'; + + createAndBuild(projectname, projectid, done); + }, CREATE_TIMEOUT); + + it('create project with unicode name, and spaces', function(done) { + var projectname = '応応応応 用用用用'; + var projectid = 'com.test.create.app4'; + + createAndBuild(projectname, projectid, done); + }, CREATE_TIMEOUT); + + it('create project with ascii+unicode name, no spaces', function(done) { + var projectname = '応応応応hello用用用用'; + var projectid = 'com.test.create.app5'; + + createAndBuild(projectname, projectid, done); + }, CREATE_TIMEOUT); + + it('create project with ascii+unicode name, and spaces', function(done) { + var projectname = '応応応応 hello 用用用用'; + var projectid = 'com.test.create.app6'; + + createAndBuild(projectname, projectid, done); + }, CREATE_TIMEOUT); + +}); diff --git a/spec/e2e/fixtures/cordova-plugin-fake/platforms/android/FakeLib/project.properties b/spec/e2e/fixtures/cordova-plugin-fake/platforms/android/FakeLib/project.properties new file mode 100644 index 00000000..131a5540 --- /dev/null +++ b/spec/e2e/fixtures/cordova-plugin-fake/platforms/android/FakeLib/project.properties @@ -0,0 +1,15 @@ +# 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 edit +# "ant.properties", and override values to adapt the script to your +# project structure. +# +# To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): +#proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt + +android.library=true +# Project target. +target=android-9 diff --git a/spec/e2e/fixtures/cordova-plugin-fake/plugin.xml b/spec/e2e/fixtures/cordova-plugin-fake/plugin.xml new file mode 100644 index 00000000..2f5538d1 --- /dev/null +++ b/spec/e2e/fixtures/cordova-plugin-fake/plugin.xml @@ -0,0 +1,44 @@ + + + + + Fake + + + Fake plugin to test plugin installation and properties parsing on Android. + + + Apache 2.0 + + + + + + + + + + + + + diff --git a/spec/e2e/helpers/projectActions.js b/spec/e2e/helpers/projectActions.js new file mode 100644 index 00000000..1c67c642 --- /dev/null +++ b/spec/e2e/helpers/projectActions.js @@ -0,0 +1,151 @@ +/* + 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. + */ + +var PluginInfoProvider = require('cordova-common').PluginInfoProvider, + shell = require('shelljs'), + cp = require('child_process'), + path = require('path'), + util = require('util'); + +var cordova_bin = path.join(__dirname, '../../../bin'); + +/** + * Creates a project using platform create script with given parameters + * @param {string} projectname - name of the project + * @param {string} projectid - id of the project + * @param {string} platformpath - path to the platform + * @param {function} callback - function which is called (without arguments) when the project is created or (with error object) when error occurs + */ +module.exports.createProject = function (projectname, projectid, platformpath, callback) { + // platformpath is optional + if (!callback && typeof platformpath === 'function') { + callback = platformpath; + platformpath = null; + } + var projectDirName = getDirName(projectid); + var createScriptPath = platformpath ? path.join(platformpath, 'bin/create') : path.join(cordova_bin, 'create'); + + // remove existing folder + module.exports.removeProject(projectid); + + // create the project + var command = util.format('%s %s %s "%s"', createScriptPath, projectDirName, projectid, projectname); + cp.exec(command, function (error, stdout, stderr) { + if (error) { + console.log(stdout); + console.error(stderr); + } + callback(error); + }); +}; + +/** + * Updates a project using platform update script with given parameters + * @param {string} projectid - id of the project + * @param {string} platformpath - path to the platform + * @param {function} callback - function which is called (without arguments) when the project is updated or (with error object) when error occurs + */ +module.exports.updateProject = function (projectid, platformpath, callback) { + // platformpath is optional + if (!callback && typeof platformpath === 'function') { + callback = platformpath; + platformpath = null; + } + var projectDirName = getDirName(projectid); + var updateScriptPath = platformpath ? path.join(platformpath, 'bin/update') : path.join(cordova_bin, 'update'); + var command = util.format('%s %s', updateScriptPath, projectDirName); + + cp.exec(command, function (error, stdout, stderr) { + if (error) { + console.log(stdout); + console.error(stderr); + } + callback(error); + }); + +}; + +/** + * Builds a project using platform build script with given parameters + * @param {string} projectid - id of the project + * @param {function} callback - function which is called (without arguments) when the project is built or (with error object) when error occurs + */ +module.exports.buildProject = function (projectid, callback) { + var projectDirName = getDirName(projectid); + var command = path.join(projectDirName, 'cordova/build'); + + cp.exec(command, function (error, stdout, stderr) { + if (error) { + console.log(stdout); + console.error(stderr); + } + callback(error); + }); +}; + +/** + * Removes a project + * @param {string} projectid - id of the project + */ +module.exports.removeProject = function (projectid) { + var projectDirName = getDirName(projectid); + shell.rm('-rf', projectDirName); +}; + +/** + * Add a plugin to a project using platform api + * @param {string} projectid - id of the project + * @param {string} plugindir - path to a plugin + * @param {function} callback - function which is called (without arguments) when the plugin is added or (with error object) when error occurs + */ +module.exports.addPlugin = function (projectid, plugindir, callback) { + var projectDirName = getDirName(projectid); + var pip = new PluginInfoProvider(); + var pluginInfo = pip.get(plugindir); + var Api = require(path.join(__dirname, '../../..', projectDirName, 'cordova', 'Api.js')); + var api = new Api('android', projectDirName); + + api.addPlugin(pluginInfo).then(function () { + callback(null); + }, function (error) { + console.error(error); + callback(error); + }); +}; + +/** + * Gets a version number from project using platform script + * @param {string} projectid - id of the project + * @param {function} callback - function which is called with platform version as an argument + */ +module.exports.getPlatformVersion = function (projectid, callback) { + var command = path.join(getDirName(projectid), 'cordova/version'); + + cp.exec(command, function (error, stdout, stderr) { + if (error) { + console.log(stdout); + console.error(stderr); + } + callback(stdout.trim()); + }); +}; + +function getDirName(projectid) { + return 'test-' + projectid; +} diff --git a/spec/e2e/plugin.spec.js b/spec/e2e/plugin.spec.js new file mode 100644 index 00000000..908e4d91 --- /dev/null +++ b/spec/e2e/plugin.spec.js @@ -0,0 +1,44 @@ +/* + 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. + */ + +var path = require('path'), + actions = require('./helpers/projectActions.js'); + +var PLUGIN_ADD_TIMEOUT = 60000; + +describe('plugin add', function() { + + it('create project and add a plugin with framework', function(done) { + var projectname = 'testpluginframework'; + var projectid = 'com.test.plugin.framework'; + var fakePluginPath = path.join(__dirname, 'fixtures/cordova-plugin-fake'); + + actions.createProject(projectname, projectid, function () { + actions.addPlugin(projectid, fakePluginPath, function (error) { + actions.removeProject(projectid); + if (error) { + console.error(error.stack); + } + expect(error).toBe(null); + done(); + }); + }); + }, PLUGIN_ADD_TIMEOUT); + +}); diff --git a/spec/e2e/update.spec.js b/spec/e2e/update.spec.js new file mode 100644 index 00000000..cd4e8bc2 --- /dev/null +++ b/spec/e2e/update.spec.js @@ -0,0 +1,97 @@ +/* + 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. + */ + +var actions = require('./helpers/projectActions.js'), + shell = require('shelljs'), + fs = require('fs'), + util = require('util'), + platformOld = { version: '4.0.0', path: 'cordova-android-old' }, + platformEdge = { version: getCurrentVersion(), path: '.' }; + +var DOWNLOAD_TIMEOUT = 2 * 60 * 1000, + UPDATE_TIMEOUT = 60 * 1000, + PLATFORM_GIT_URL = 'https://github.com/apache/cordova-android'; + +function getCurrentVersion() { + return fs.readFileSync('VERSION').toString().trim(); +} + +function testUpdate(projectname, projectid, createfrom, updatefrom, doBuild, done) { + actions.createProject(projectname, projectid, createfrom.path, function (error) { + expect(error).toBe(null); + actions.updateProject(projectid, updatefrom.path, function (error) { + expect(error).toBe(null); + actions.getPlatformVersion(projectid, function (v) { + expect(v).toEqual(updatefrom.version); + if (doBuild) { + actions.buildProject(projectid, function (error) { + expect(error).toBe(null); + actions.removeProject(projectid); + done(); + }); + } else { + actions.removeProject(projectid); + done(); + } + }); + }); + }); +} + +describe('preparing fixtures', function () { + + it('cloning old platform', function (done) { + var command = util.format('git clone %s --depth=1 --branch %s %s', + PLATFORM_GIT_URL, platformOld.version, platformOld.path); + shell.rm('-rf', platformOld.path); + shell.exec(command, { silent: true }, function (err) { + expect(err).toBe(0); + done(); + }); + }, DOWNLOAD_TIMEOUT); + +}); + +describe('update', function() { + + it('should update major version and build the project', function(done) { + var projectname = 'testupdate'; + var projectid = 'com.test.update.app1'; + + testUpdate(projectname, projectid, platformOld, platformEdge, true, done); + + }, UPDATE_TIMEOUT); + + it('should downgrade major version and build the project', function(done) { + var projectname = 'testupdate'; + var projectid = 'com.test.update.app2'; + + testUpdate(projectname, projectid, platformEdge, platformOld, true, done); + }, UPDATE_TIMEOUT); + + // TODO: After next Android release, add tests for minor/patch version update +}); + +describe('cleanup', function () { + + it('remove cloned old platform', function() { + shell.rm('-rf', platformOld.path); + }); + +});