From e889ab5312f48256c30048ec2d7334309382e781 Mon Sep 17 00:00:00 2001 From: David Douglas Date: Wed, 17 Feb 2016 15:07:21 +0000 Subject: [PATCH] Updates to work with Cordova 6. Resolves #122 --- app/jxcore/gulpfile.js | 49 +++++++++++++++--------------- app/jxcore/hook.js | 9 +++--- app/jxcore/package.json | 2 +- app/jxcore/public/test/editor.html | 4 +++ app/jxcore/public/test/home.html | 4 +++ app/jxcore/public/test/login.html | 4 +++ config.xml | 3 +- readme.md | 29 +++++++++--------- test/helpers/caps.js | 7 +++-- test/helpers/defaults.js | 5 +++ test/postcardapp.js | 28 +++++++++++++++-- test/readme.md | 14 ++++++--- 12 files changed, 104 insertions(+), 54 deletions(-) diff --git a/app/jxcore/gulpfile.js b/app/jxcore/gulpfile.js index f29e1a3..cb2dad7 100755 --- a/app/jxcore/gulpfile.js +++ b/app/jxcore/gulpfile.js @@ -232,13 +232,22 @@ gulp.task('minify:html', function(){ }); // Copy Cordova javascript and plugin source into the JXcore app's 'public' dir +gulp.task('cordova:xplatform', ['cordova:config','build:xplatform']); gulp.task('cordova:android', ['cordova:config','build:android']); gulp.task('cordova:ios', ['cordova:config','build:ios']); +gulp.task('build:xplatform', function(cb){ + return runSequence( + 'cordova:clean', + 'cordova:androidCopyCordovaScripts', + 'cordova:iosCopyCordovaScripts', + 'cordova:semaphore', + cb); +}); + gulp.task('build:android', function(cb){ return runSequence( 'cordova:clean', - 'cordova:cleanCordovaScripts', 'cordova:androidCopyCordovaScripts', 'cordova:semaphore', cb); @@ -247,46 +256,38 @@ gulp.task('build:android', function(cb){ gulp.task('build:ios', function(cb){ return runSequence( 'cordova:clean', - 'cordova:cleanCordovaScripts', 'cordova:iosCopyCordovaScripts', 'cordova:semaphore', cb); }); -// remove platform specific Cordova source before building -gulp.task('cordova:cleanCordovaScripts', function(cb){ - console.log("Clean Cordova platform source:", paths.build); - var removables = [ - paths.build+'public/cordova.js', - paths.build+'public/cordova_plugins.js', - paths.build+'public/plugins/**/*', - paths.build+'public/cordova-js-src/**/*' - ]; - return del(removables, {force: true}, cb); -}); - gulp.task('cordova:androidCopyCordovaScripts', function(cb){ - return copyCordovaScripts(cb,'platforms/android/assets/www/'); + return copyCordovaScripts(cb, + 'platforms/android/platform_www/', + 'platforms/android/assets/www/'); }); gulp.task('cordova:iosCopyCordovaScripts', function(cb){ - return copyCordovaScripts(cb,'platforms/ios/www/'); + return copyCordovaScripts(cb, + 'platforms/ios/platform_www/', + 'platforms/ios/www/'); }); -var copyCordovaScripts = function(cb, path) { - console.log("copy Cordova scripts and plugins from:", path); +var copyCordovaScripts = function(cb, platform_www, www) { + var dest = www+'jxcore/public'; + console.log("copy Cordova scripts and plugins from:", platform_www); // NB: Cordova source paths may not exist during initial 'cordova platform add ...' return gulp.src([ - path+'cordova.js', - path+'cordova_plugins.js', - path+'plugins/**/*', - path+'cordova-js-src/**/*' + platform_www+'cordova.js', + platform_www+'cordova_plugins.js', + platform_www+'plugins/**/*', + platform_www+'cordova-js-src/**/*' ], { dot: true, - base: path + base: platform_www }) - .pipe(gulp.dest(paths.build+'public'), cb); + .pipe(gulp.dest(dest), cb); }; // clean tmp working files diff --git a/app/jxcore/hook.js b/app/jxcore/hook.js index 79b74a9..2453988 100755 --- a/app/jxcore/hook.js +++ b/app/jxcore/hook.js @@ -13,12 +13,11 @@ module.exports = function(context) { // default gulp task with cordova build hook var gulpTask = 'cordova:build'; - if (context.hook === 'after_prepare' ){ + if (context.hook === 'after_prepare'){ if (context.opts.platforms.length === 1){ - gulpTask = 'cordova:'+context.opts.platforms[0]; + gulpTask = 'cordova:'+context.opts.platforms[0]; // build single platform } else if (context.opts.platforms.length>1) { - // warn when using 'cordova build' as this command targets mutiple platforms (android,ios) and you can't copy specific cordova platform plugins into build with this multi-platform hook. - console.warn("Warning: Please run 'cordova build ios' or 'cordova build android' after"); + gulpTask = 'cordova:xplatform'; // build multiple platforms (android,ios) } } console.log("start gulp task:", gulpTask); @@ -30,7 +29,7 @@ module.exports = function(context) { // Note: Using a workaround to check for gulp script is completed using a semaphore file as 'task_stop' event fires after first task and not after all tasks have been completed. var inter = setInterval(function(){ if ( fs.existsSync(semaphoreFile) ) { - console.log(gulpTask, "should be completed."); + console.log(gulpTask, "task should be completed."); clearInterval(inter); fs.unlinkSync(semaphoreFile); deferral.resolve(); diff --git a/app/jxcore/package.json b/app/jxcore/package.json index 2314b7d..41f8a8a 100644 --- a/app/jxcore/package.json +++ b/app/jxcore/package.json @@ -12,7 +12,7 @@ "leveldown-mobile": "^1.0.7", "pouchdb": "5.0.0", "socket.io": "^1.3.6", - "thali": "~2.0.4" + "thali": "~2.1.0" }, "devDependencies": { "crisper": "^2.0.1", diff --git a/app/jxcore/public/test/editor.html b/app/jxcore/public/test/editor.html index f37601e..81d030e 100644 --- a/app/jxcore/public/test/editor.html +++ b/app/jxcore/public/test/editor.html @@ -17,6 +17,10 @@ + + diff --git a/app/jxcore/public/test/home.html b/app/jxcore/public/test/home.html index c13e090..f6007e8 100644 --- a/app/jxcore/public/test/home.html +++ b/app/jxcore/public/test/home.html @@ -17,6 +17,10 @@ + + diff --git a/app/jxcore/public/test/login.html b/app/jxcore/public/test/login.html index e587929..373d458 100644 --- a/app/jxcore/public/test/login.html +++ b/app/jxcore/public/test/login.html @@ -14,6 +14,10 @@ + + diff --git a/config.xml b/config.xml index 6e22e2d..393989a 100644 --- a/config.xml +++ b/config.xml @@ -68,6 +68,7 @@ + @@ -85,5 +86,5 @@ - + diff --git a/readme.md b/readme.md index 67c81f6..f560226 100644 --- a/readme.md +++ b/readme.md @@ -52,12 +52,12 @@ set PATH=%PATH%;%ANDROID_HOME%\tools;%ANDROID_HOME%\platform-tools Follow the instructions at [http://jxcore.com/downloads/](http://jxcore.com/downloads/). Their download page is a little confusing so please pay attention to the section at the top that says in a tiny little font 'Installation'. When you're done, check that the installation worked: ``` $ jx -jxv -v 0.3.0.7 +v 0.3.1.0 ``` ## Install Apache Cordova -Ensure that Apache Cordova is installed globally by using JXcore's `jx install` command. +Ensure that Apache Cordova 6 is installed globally by using JXcore's `jx install` command. Mac/Linux: ``` @@ -94,22 +94,21 @@ You will need two (it's a peer to peer system) Android devices running at least ```shell git clone https://github.com/thaliproject/postcardapp.git -cd postcardapp +cd postcardapp/app/jxcore +jx npm install --production --autoremove "*.gz" -cordova platform add android -cordova platform add ios +# update JXcore Mobile to 0.1.1 +jxc install --force -cd app/jxcore -jx npm install --production --autoremove "*.gz" +jx npm install +find ./node_modules -name "*.gz" -type f -delete bower install find ./public/bower_components -name "*.gz" -type f -delete -jx npm install --autoremove "*.gz" -find ./node_modules -name "*.gz" -type f -delete -cordova prepare android +cordova platform add android cordova build android -cordova prepare ios +cordova platform add ios cordova build ios ``` @@ -118,11 +117,13 @@ On Windows one needs to use [Git Bash](https://git-scm.com/download/win) or equi ## Running in development environment on localhost You will also need to copy the Thali_CordovaPlugin 'mockmobile.js' script if you want run in development mode. This allows native methods to be called on the desktop when UX testing the web app. ``` -cd app/jxcore -jx npm install --autoremove "*.gz" +cd postcardapp/app/jxcore +jx npm install +find ./node_modules -name "*.gz" -type f -delete bower install find ./public/bower_components -name "*.gz" -type f -delete -cp -v ../../thaliDontCheckIn/Thali_CordovaPlugin-master/test/www/jxcore/bv_tests/mockmobile.js node_modules/thali/ + +cp -v ../../thaliDontCheckIn/Thali_CordovaPlugin-npmv2.1.0/test/www/jxcore/bv_tests/mockmobile.js node_modules/thali/ jx npm run localhost ``` diff --git a/test/helpers/caps.js b/test/helpers/caps.js index 7072682..099ae41 100644 --- a/test/helpers/caps.js +++ b/test/helpers/caps.js @@ -3,7 +3,7 @@ var path = require("path"); exports.iosSimulator = { app: path.resolve(__dirname, '../../platforms/ios/build/emulator/PostCardApp.app'), fullReset: true, - autoWebview: true, + autoWebview: false, platformName: 'iOS', platformVersion: '9.2', deviceName: 'iPhone 5s', @@ -14,7 +14,7 @@ exports.iosDevice = { app: path.resolve(__dirname, '../../platforms/ios/build/device/PostCardApp.app'), bundleId: 'org.thaliproject.postcardapp', fullReset: true, - autoWebview: true, + autoWebview: false, platformName: 'iOS', platformVersion: '9.2.1', deviceName: 'iPhone 6', @@ -24,7 +24,8 @@ exports.iosDevice = { exports.androidDevice = { app: path.resolve(__dirname, '../../platforms/android/build/outputs/apk/android-debug.apk'), fullReset: true, - autoWebview: true, + autoWebview: false, + autoWebviewTimeout: 6000, platformName: 'Android', platformVersion: '5.0.2', deviceName: 'XT1072', diff --git a/test/helpers/defaults.js b/test/helpers/defaults.js index 636cd39..83f457f 100644 --- a/test/helpers/defaults.js +++ b/test/helpers/defaults.js @@ -4,6 +4,11 @@ module.exports = { wait : { short: 1000, long: 6000, + splashscreen: 1000, + }, + + timeout : { + app: 36000, }, username: "bob", diff --git a/test/postcardapp.js b/test/postcardapp.js index ef5b06a..53d0afa 100644 --- a/test/postcardapp.js +++ b/test/postcardapp.js @@ -1,7 +1,11 @@ "use strict"; -require("./helpers/setup"); +if (!require('fs').existsSync(__dirname+"/node_modules")) { + console.log("'node_modules' folder not found. Please refer to readme.md"); + return; +} +require("./helpers/setup"); var wd = require("wd"), fs = require('fs'), path = require('path'), @@ -30,6 +34,25 @@ describe("PostcardApp", function () { return _.clone(caps.androidEmulator); } + // workaround method to find webview context as 'autoWebview' is not finding webview context following Cordova 6 update + function switchContextToWebview(driver) { + return driver + .sleep(defaults.wait.splashscreen) + .contexts() + .then( function(contexts){ + if(contexts.length<2) { + console.error("Could not find webview in contexts:", contexts); + throw new Error("Stopping tests as webview context was not found."); + return driver.quit(); + } + var webviewContext = _.find(contexts, function(context){ + return context.indexOf('WEBVIEW') !== -1; + }); + console.log('webview context:', webviewContext); + return driver.context(webviewContext).setAsyncScriptTimeout(defaults.timeout.app); + }); + } + before(function () { var serverConfig = serverConfigs.local; @@ -54,7 +77,7 @@ describe("PostcardApp", function () { // init driver with capabilities driver = driver.init(cap); - return driver; + return switchContextToWebview(driver); }); after(function () { @@ -70,6 +93,7 @@ describe("PostcardApp", function () { // Tests it("should redirect to jxcore express app 'http://localhost'", function () { return driver + .waitForConditionInBrowser("document.querySelectorAll('div').length > 0", defaults.timeout.app) .waitForElementByCss("div", asserters.isDisplayed, defaults.wait.long) .safeEval('window.location.href').should.eventually.contain('http://localhost:'); }); diff --git a/test/readme.md b/test/readme.md index 7893dd5..9031c74 100644 --- a/test/readme.md +++ b/test/readme.md @@ -93,6 +93,12 @@ cordova build ios --device ``` *This should build the Postcard app in 'platforms/ios/build/device' directory.* +### Install Webkit Debug Proxy +Use [homebrew](http://brew.sh/) to install [Webkit Debug Proxy](https://github.com/google/ios-webkit-debug-proxy) on Mac: +``` +brew install ios-webkit-debug-proxy +``` + ## Running tests on iOS device 1. The iOS device will need to be setup as a developer device as well as **UIAutomation** enabled in *Settings > Developer*. 2. Find iOS device's name, UDID and iOS version: @@ -113,11 +119,11 @@ cordova build ios --device appium ``` -5. Run tests for iOS device using iOS device's name, UDID and iOS version: +5. Run tests for iOS device using iOS device's UDID, name and iOS version: ``` cd ./test - mocha postcardapp.js --cap=iosDevice --deviceName="iPhone 5s" --udid="YOUR_IOS_DEVICE_UDID" --platformVersion="9.2" + mocha postcardapp.js --cap=iosDevice --udid="YOUR_IOS_DEVICE_UDID" --deviceName="iPhone 6" --platformVersion="9.2.1" ``` # Appium server troubleshooting @@ -125,13 +131,13 @@ cordova build ios --device ### Android device - Appium error `unknown error: Chrome version must be >= 43.0.2357.0` Solution: The [Android WebView]( https://play.google.com/store/apps/details?id=com.google.android.webview) needs updated. Open *Settings > Apps > All > Android System WebView* to check the version. -- Tests can't run if the screen locks. +- Tests can't run if the screen locks. Workaround: Temporarily turn off screen lock when testing - open *Settings > Security > Screen Lock* and select *None*. ### iOS device - Appium error `Command failed: /bin/sh -c ideviceinstaller` Solution: If you get an ApplicationVerificationFailed error with 'ideviceinstaller' then make sure the app builds in Xcode and deploys to your device. Then rebuild for iOS device using `cordova build ios --device` -- Tests can't run if the screen locks. +- Tests can't run if the screen locks. Workaround: Temporarily turn off or increase Auto-Lock time when testing - open *Settings > General > Auto-Lock* and set to *5 Minutes* or *Never*. If you experience any other issues the official [Appium troubleshooting ](http://appium.io/slate/en/1.4/?javascript#troubleshooting-appium) docs may come in handy.