Repository: cordova-paramedic
Updated Branches:
  refs/heads/master 9655060c7 -> 739c4326b


Code changes for Collecting Device Logs - Killing the Emulator Process - 
Setting Permissions in iOS


Project: http://git-wip-us.apache.org/repos/asf/cordova-paramedic/repo
Commit: http://git-wip-us.apache.org/repos/asf/cordova-paramedic/commit/739c4326
Tree: http://git-wip-us.apache.org/repos/asf/cordova-paramedic/tree/739c4326
Diff: http://git-wip-us.apache.org/repos/asf/cordova-paramedic/diff/739c4326

Branch: refs/heads/master
Commit: 739c4326ba8c5014d4776e53b28e6da817c85cfb
Parents: 9655060
Author: Sarangan Rajamanickam <saraj...@microsoft.com>
Authored: Wed Apr 13 10:59:19 2016 -0700
Committer: Raghav Katyal <rakat...@microsoft.com>
Committed: Thu Apr 28 12:07:04 2016 -0700

----------------------------------------------------------------------
 README.md                      |  34 +++++++++-
 lib/ParamedicConfig.js         |  50 ++++++++++++---
 lib/ParamedicKill.js           | 100 +++++++++++++++++++++++++++++
 lib/ParamedicLog.js            |  98 ++++++++++++++++++++++++++++
 lib/ParamediciOSPermissions.js |  42 ++++++++++++
 lib/Reporters.js               |   6 +-
 lib/paramedic.js               |  68 +++++++++++++++-----
 lib/utils/index.js             |   5 +-
 lib/utils/utilities.js         | 123 ++++++++++++++++++++++++++++++++++++
 main.js                        |  40 ++++++++++--
 package.json                   |   3 +-
 11 files changed, 532 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/README.md
----------------------------------------------------------------------
diff --git a/README.md b/README.md
index 3ad4a90..184395e 100644
--- a/README.md
+++ b/README.md
@@ -111,12 +111,44 @@ cordova-paramedic --platform ios --plugin 
cordova-plugin-inappbrowser --verbose
 
 ####--timeout (optional)
 
-Time in millisecs to wait for tests to pass|fail (defaults to 10 minutes). 
+Time in millisecs to wait for tests to pass|fail (defaults to 10 minutes).
 
 ```
 cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser 
--timeout 30000
 ```
 
+####--outputDir (optional)
+
+Directory location to store test results in junit format and the device logs
+
+```
+cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser 
--outputDir /Users/sampleuser/testresults
+```
+
+####--cleanUpAfterRun (optional)
+
+Flag to indicate the sample application folder must be deleted.
+
+```
+cordova-paramedic --platform ios --plugin cordova-plugin-inappbrowser 
--cleanUpAfterRun
+```
+
+####--logMins (optional)
+
+Windows only parameter to indicate the duration for which the device logs to 
be fetched.
+
+```
+cordova-paramedic --platform windows --plugin cordova-plugin-inappbrowser 
--logMins 15
+```
+
+####--tccDb (optional)
+
+iOS only parameter. The path to the sample TCC DB file, with permissions, to 
be copied to the simulator.
+
+```
+cordova-paramedic --platform ios --plugin cordova-plugin-contacts --tccDbPath 
tcc.db
+```
+
 ## Paramedic configuration file
 
 Configuration file is used when no parameters are passed to 
`cordova-paramedic` call or explicitly specified via `--config` parameter:

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/ParamedicConfig.js
----------------------------------------------------------------------
diff --git a/lib/ParamedicConfig.js b/lib/ParamedicConfig.js
index 11b5c0c..52ab9c2 100644
--- a/lib/ParamedicConfig.js
+++ b/lib/ParamedicConfig.js
@@ -17,9 +17,9 @@
     under the License.
 */
 
-var DEFAULT_START_PORT = 8008;
-var DEFAULT_END_PORT = 8018;
-var DEFAULT_TIMEOUT = 10 * 60 * 1000; // 10 minutes in msec - this will become 
a param
+var DEFAULT_START_PORT  = 8008;
+var DEFAULT_END_PORT    = 8018;
+var DEFAULT_TIMEOUT     = 10 * 60 * 1000; // 10 minutes in msec - this will 
become a param
 
 function ParamedicConfig(json) {
     this._config = json;
@@ -36,8 +36,10 @@ ParamedicConfig.parseFromArguments = function (argv) {
         startPort:         argv.startport || argv.port,
         endPort:           argv.endport || argv.port,
         externalServerUrl: argv.externalServerUrl,
-        reportSavePath:    !!argv.reportSavePath? argv.reportSavePath: 
undefined,
-        cleanUpAfterRun:   !!argv.cleanUpAfterRun? true: false
+        outputDir:         !!argv.outputDir? argv.outputDir: null,
+        cleanUpAfterRun:   !!argv.cleanUpAfterRun? true: false,
+        logMins:           !!argv.logMins? argv.logMins: null,
+        tccDb:             !!argv.tccDbPath? argv.tccDb: null
     });
 };
 
@@ -49,11 +51,15 @@ ParamedicConfig.prototype.getUseTunnel = function () {
     return this._config.useTunnel;
 };
 
-ParamedicConfig.prototype.getReportSavePath = function () {
-    return this._config.reportSavePath;
+ParamedicConfig.prototype.getOutputDir = function () {
+    return this._config.outputDir;
 };
 
-ParamedicConfig.prototype.getShouldCleanUpAfterRun = function () {
+ParamedicConfig.prototype.setOutputDir = function (outputDir) {
+    this._config.outputDir = outputDir;
+};
+
+ParamedicConfig.prototype.shouldCleanUpAfterRun = function () {
     return this._config.cleanUpAfterRun;
 };
 
@@ -61,10 +67,18 @@ ParamedicConfig.prototype.getPlatform = function() {
     return this._config.platform;
 };
 
+ParamedicConfig.prototype.setPlatform = function(platform) {
+    this._config.platform = platform;
+};
+
 ParamedicConfig.prototype.getAction = function() {
     return this._config.action;
 };
 
+ParamedicConfig.prototype.setAction = function(action) {
+    this._config.action = action;
+};
+
 ParamedicConfig.prototype.getArgs = function() {
     return this._config.args;
 };
@@ -77,6 +91,10 @@ ParamedicConfig.prototype.getPlugins = function () {
     return this._config.plugins;
 };
 
+ParamedicConfig.prototype.setPlugins = function (plugins) {
+    this._config.plugins = Array.isArray(plugins) ? plugins : [plugins];
+};
+
 ParamedicConfig.prototype.getExternalServerUrl= function () {
     return this._config.externalServerUrl;
 };
@@ -104,4 +122,20 @@ ParamedicConfig.prototype.getTimeout = function() {
     return DEFAULT_TIMEOUT;
 };
 
+ParamedicConfig.prototype.getLogMins = function() {
+    return this._config.logMins;
+};
+
+ParamedicConfig.prototype.setLogMins = function(logMins) {
+    this._config.logMins = logMins;
+};
+
+ParamedicConfig.prototype.setTccDb = function(tccDb) {
+    this._config.tccDb = tccDb;
+};
+
+ParamedicConfig.prototype.getTccDb = function() {
+    return this._config.tccDb;
+};
+
 module.exports = ParamedicConfig;

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/ParamedicKill.js
----------------------------------------------------------------------
diff --git a/lib/ParamedicKill.js b/lib/ParamedicKill.js
new file mode 100644
index 0000000..e81b8bd
--- /dev/null
+++ b/lib/ParamedicKill.js
@@ -0,0 +1,100 @@
+#!/usr/bin/env node
+
+"use strict";
+
+var shelljs = require("shelljs");
+var util    = require("./utils").utilities;
+var logger  = require('./utils').logger;
+
+function ParamedicKill(platform) {
+    this.platform = platform;
+}
+
+ParamedicKill.prototype.kill = function() {
+    // shell config
+    shelljs.config.fatal  = false;
+    shelljs.config.silent = false;
+
+    // get platform tasks
+    var platformTasks = this.tasksOnPlatform(this.platform);
+
+    if (platformTasks.length < 1) {
+        console.warn("no known tasks to kill");
+        return;
+    }
+
+    // kill them
+    this.killTasks(platformTasks);
+
+    if (this.platform === util.ANDROID) {
+        this.killAdbServer();
+    }
+
+}
+
+ParamedicKill.prototype.tasksOnPlatform = function (platformName) {
+    var tasks = [];
+    switch (platformName) {
+    case util.WINDOWS:
+        tasks = ["WWAHost.exe", "Xde.exe"];
+        break;
+    case util.IOS:
+        tasks = ["Simulator", "iOS Simulator"];
+        break;
+    case util.ANDROID:
+        if (util.isWindows()) {
+            tasks = ["emulator-arm.exe"];
+        } else {
+            tasks = ["emulator64-x86", "emulator64-arm"];
+        }
+        break;
+    }
+    return tasks;
+}
+
+ParamedicKill.prototype.killTasks = function (taskNames) {
+    if (!taskNames || taskNames.length < 1) {
+        return;
+    }
+
+    var command = this.getKillCommand(taskNames);
+
+    logger.info("running the following command:");
+    logger.info("    " + command);
+
+    var killTasksResult = shelljs.exec(command, {silent: false, async: false 
});
+    if (killTasksResult.code !== 0) {
+        console.warn("WARNING: kill command returned " + killTasksResult.code);
+    }
+}
+
+ParamedicKill.prototype.getKillCommand = function (taskNames) {
+    var cli;
+    var args;
+
+    if (util.isWindows()) {
+        cli  = "taskkill /F";
+        args = taskNames.map(function (name) { return "/IM \"" + name + "\""; 
});
+    } else {
+        cli  = "killall -9";
+        args = taskNames.map(function (name) { return "\"" + name + "\""; });
+    }
+
+    return cli + " " + args.join(" ");
+}
+
+ParamedicKill.prototype.killAdbServer = function () {
+    logger.info("Killing adb server");
+    var killServerCommand = "adb kill-server";
+
+    logger.info("Running the following command:");
+    logger.info("    " + killServerCommand);
+
+    var killServerResult = shelljs.exec(killServerCommand, {silent: false, 
async: false});
+    if (killServerResult.code !== 0) {
+        logger.error("Failed killing adb server with code: " + 
killServerResult.code);
+    }
+    logger.info("Finished killing adb server");
+}
+
+module.exports = ParamedicKill;

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/ParamedicLog.js
----------------------------------------------------------------------
diff --git a/lib/ParamedicLog.js b/lib/ParamedicLog.js
new file mode 100644
index 0000000..ed47b7d
--- /dev/null
+++ b/lib/ParamedicLog.js
@@ -0,0 +1,98 @@
+#!/usr/bin/env node
+
+/* jshint node: true */
+
+"use strict";
+
+var shelljs  = require("shelljs");
+var fs       = require("fs");
+var path     = require("path-extra");
+var util     = require('./utils').utilities;
+var logger   = require('./utils').logger;
+
+
+function ParamedicLog(platform, appPath, outputDir){
+    this.platform = platform;
+    this.appPath = appPath;
+    this.outputDir = outputDir;
+}
+
+ParamedicLog.prototype.logIOS = function (appPath) {
+    var simId = util.getSimId();
+
+    if (simId) {
+        // Now we can print out the log file
+        var logPath = path.join(path.homedir(), "Library", "Logs", 
"CoreSimulator", simId, "system.log");
+        var logCommand = "cat " + logPath;
+        this.generateLogs(logCommand);
+    } else {
+        logger.error("Failed to find ID of mobilespec simulator");
+    }
+}
+
+ParamedicLog.prototype.logWindows = function (appPath, logMins) {
+    var logScriptPath = path.join(appPath, "platforms", "windows", "cordova", 
"log.bat");
+    if (fs.existsSync(logScriptPath)) {
+        var mins = util.DEFAULT_LOG_TIME;
+        if (logMins) {
+            mins = logMins + util.DEFAULT_LOG_TIME_ADDITIONAL;
+        }
+        var logCommand = logScriptPath + " --dump --mins " + mins;
+        this.generateLogs(logCommand);
+    }
+}
+
+ParamedicLog.prototype.logAndroid = function (){
+    var logCommand = "adb logcat -d -v time";
+
+    var numDevices = util.countAndroidDevices();
+    if (numDevices != 1) {
+        logger.error("there must be exactly one emulator/device attached");
+        return;
+    }
+    this.generateLogs(logCommand);
+}
+
+ParamedicLog.prototype.generateLogs = function(logCommand) {
+    var logFile = this.getLogFileName();
+    logger.info('Running Command: ' + logCommand);
+
+    var result = shelljs.exec(logCommand, {silent: true, async: false});
+    if (result.code > 0) {
+        logger.error("Failed to run command: " + logCommand);
+        logger.error("Failure code: " + result.code);
+        return;
+    }
+
+    try {
+        fs.writeFileSync(logFile, result.output);
+    } catch (ex) {
+        logger.error("Cannot write the log results to the file. " + ex);
+    }
+}
+
+ParamedicLog.prototype.getLogFileName = function() {
+    return path.join(this.outputDir, this.platform + "_logs.txt");
+}
+
+ParamedicLog.prototype.collectLogs = function (logMins){
+    shelljs.config.fatal  = false;
+    shelljs.config.silent = false;
+
+    switch (this.platform) {
+        case util.ANDROID:
+            this.logAndroid();
+            break;
+        case util.IOS:
+            this.logIOS(this.appPath);
+            break;
+        case util.WINDOWS:
+            this.logWindows(this.appPath, logMins);
+            break;
+        default:
+            logger.error("Logging is unsupported for " + platform);
+            break;
+    }
+}
+
+module.exports = ParamedicLog;

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/ParamediciOSPermissions.js
----------------------------------------------------------------------
diff --git a/lib/ParamediciOSPermissions.js b/lib/ParamediciOSPermissions.js
new file mode 100644
index 0000000..c7e0317
--- /dev/null
+++ b/lib/ParamediciOSPermissions.js
@@ -0,0 +1,42 @@
+#!/usr/bin/env node
+
+/* jshint node: true */
+var path     = require('path');
+var fs       = require('fs');
+var shelljs  = require("shelljs");
+var logger   = require('./utils').logger;
+var util     = require('./utils').utilities;
+
+var TCC_FOLDER_PERMISSION = 0755;
+
+function ParamediciOSPermissions(appName, tccDb) {
+    this.appName = appName;
+    this.tccDb   = tccDb;
+}
+
+ParamediciOSPermissions.prototype.updatePermissions = function(serviceList){
+    var simulatorsFolder   = util.getSimulatorsFolder();
+    var simId              = util.getSimId();
+    logger.info('Sim Id is: ' + simId);
+    var destinationTCCFile = path.join(simulatorsFolder, simId, 
'/data/Library/TCC/TCC.db');
+
+    if(!util.doesFileExist(destinationTCCFile)) {
+        // No TCC.db file exists by default. So, Copy the new TCC.db file
+        var destinationTCCFolder = path.join(simulatorsFolder, simId, 
'/data/Library/TCC');
+        if(!util.doesFileExist(destinationTCCFolder)){
+            fs.mkdir(destinationTCCFolder, TCC_FOLDER_PERMISSION);
+        }
+        logger.info("Copying TCC Db file to " + destinationTCCFolder);
+        shelljs.cp(this.tccDb, destinationTCCFolder)
+    }
+
+    for(var i = 0; i < serviceList.length; i++) {
+        var command = util.getSqlite3InsertionCommand(destinationTCCFile, 
serviceList[i], this.appName);
+        logger.info("Running Command: " + command);
+        // If the service has an entry already, the insert command will fail.
+        // But, such a failure is intentionally not handled here.
+        shelljs.exec(command, {silent: true, async: false});
+    }
+}
+
+module.exports = ParamediciOSPermissions;

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/Reporters.js
----------------------------------------------------------------------
diff --git a/lib/Reporters.js b/lib/Reporters.js
index 9c012c8..2f6fcb8 100644
--- a/lib/Reporters.js
+++ b/lib/Reporters.js
@@ -20,11 +20,11 @@
 var JasmineSpecReporter = require('jasmine-spec-reporter'),
     jasmineReporters    = require('jasmine-reporters');
 
-module.exports = function(reportSavePath) {
+module.exports = function(outputDir) {
     var reporters = [new JasmineSpecReporter({displayPendingSummary: false, 
displaySuiteNumber: true})];
 
-    if (reportSavePath) {
-        reporters.push(new jasmineReporters.JUnitXmlReporter({savePath: 
reportSavePath, consolidateAll: false}));
+    if (outputDir) {
+        reporters.push(new jasmineReporters.JUnitXmlReporter({savePath: 
outputDir, consolidateAll: false}));
     }
 
     return reporters;

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/paramedic.js
----------------------------------------------------------------------
diff --git a/lib/paramedic.js b/lib/paramedic.js
index be50f90..1f68e6a 100644
--- a/lib/paramedic.js
+++ b/lib/paramedic.js
@@ -17,22 +17,29 @@
     under the License.
 */
 
-var exec = require('./utils').exec,
-    shell = require('shelljs'),
-    Server = require('./LocalServer'),
-    Q = require('q'),
-    tmp = require('tmp'),
-    PluginsManager = require('./PluginsManager'),
-    path = require('path'),
-    Q = require('q'),
-    fs = require('fs'),
-    getReporters = require('./Reporters'),
-    logger = require('./utils').logger;
+var exec    = require('./utils').exec;
+var shell   = require('shelljs');
+var Server  = require('./LocalServer');
+var tmp     = require('tmp');
+var path    = require('path');
+var Q       = require('q');
+var fs      = require('fs');
+var logger  = require('./utils').logger;
+var util    = require('./utils').utilities;
+var PluginsManager  = require('./PluginsManager');
+var getReporters    = require('./Reporters');
+var ParamedicKill   = require('./ParamedicKill');
+var ParamedicLog    = require('./ParamedicLog');
+var ParamediciOSPermissions = require('./ParamediciOSPermissions');
 
 // Time to wait for initial device connection.
 // If device has not connected within this interval the tests are stopped.
 var INITIAL_CONNECTION_TIMEOUT = 300000; // 5mins
 
+var applicationsToGrantPermission = [
+    'kTCCServiceAddressBook'
+];
+
 function ParamedicRunner(config, _callback) {
     this.tempFolder = null;
     this.pluginsManager = null;
@@ -47,6 +54,7 @@ ParamedicRunner.prototype.run = function() {
 
     return Q().then(function() {
         self.createTempProject();
+        shell.pushd(self.tempFolder.name);
         self.prepareProjectToRunTests();
         return Server.startServer(self.config.getPorts(), 
self.config.getExternalServerUrl(), self.config.getUseTunnel());
     })
@@ -62,6 +70,8 @@ ParamedicRunner.prototype.run = function() {
         return self.runTests();
     })
     .fin(function() {
+        self.collectDeviceLogs();
+        self.killEmulatorProcess();
         self.cleanUpProject();
     });
 };
@@ -71,7 +81,6 @@ ParamedicRunner.prototype.createTempProject = function() {
     tmp.setGracefulCleanup();
     logger.info("cordova-paramedic: creating temp project at " + 
this.tempFolder.name);
     exec('cordova create ' + this.tempFolder.name);
-    shell.pushd(this.tempFolder.name);
 };
 
 ParamedicRunner.prototype.prepareProjectToRunTests = function() {
@@ -79,6 +88,7 @@ ParamedicRunner.prototype.prepareProjectToRunTests = 
function() {
     this.setUpStartPage();
     this.installPlatform();
     this.checkPlatformRequirements();
+    this.setPermissions();
 };
 
 ParamedicRunner.prototype.installPlugins = function() {
@@ -105,13 +115,25 @@ ParamedicRunner.prototype.checkPlatformRequirements = 
function() {
     logger.normal("cordova-paramedic: checking requirements for platform " + 
this.config.getPlatformId());
     var result = exec('cordova requirements ' + this.config.getPlatformId());
 
-    if (result.code !== 0) 
+    if (result.code !== 0)
         throw new Error('Platform requirements check has failed!');
 };
 
+ParamedicRunner.prototype.setPermissions = function() {
+    if(this.config.getPlatformId() === 'ios'){
+        logger.info("cordova-paramedic: Setting required permissions.");
+        var tccDb        = this.config.getTccDb();
+        if(tccDb) {
+            var appName                 = util.PARAMEDIC_DEFAULT_APP_NAME;
+            var paramediciOSPermissions = new ParamediciOSPermissions(appName, 
tccDb);
+            
paramediciOSPermissions.updatePermissions(applicationsToGrantPermission);
+        }
+    }
+};
+
 ParamedicRunner.prototype.injectReporters = function() {
     var self = this;
-    var reporters = getReporters(self.config.getReportSavePath());
+    var reporters = getReporters(self.config.getOutputDir());
 
     ['jasmineStarted', 'specStarted', 'specDone',
     'suiteStarted', 'suiteDone', 'jasmineDone'].forEach(function(route) {
@@ -210,13 +232,29 @@ ParamedicRunner.prototype.waitForConnection = function() {
 };
 
 ParamedicRunner.prototype.cleanUpProject = function() {
-    if(this.config.getShouldCleanUpAfterRun()) {
+    if(this.config.shouldCleanUpAfterRun()) {
         logger.info("cordova-paramedic: Deleting the application: " + 
this.tempFolder.name);
         shell.popd();
         shell.rm('-rf', this.tempFolder.name);
     }
 };
 
+ParamedicRunner.prototype.killEmulatorProcess = function() {
+    if(this.config.shouldCleanUpAfterRun()){
+        logger.info("cordova-paramedic: Killing the emulator process.");
+        var paramedicKill = new ParamedicKill(this.config.getPlatformId());
+        paramedicKill.kill();
+    }
+};
+
+ParamedicRunner.prototype.collectDeviceLogs = function() {
+    logger.info("Collecting logs for the devices.");
+    var outputDir    = this.config.getOutputDir()? this.config.getOutputDir(): 
this.tempFolder.name;
+    var logMins      = this.config.getLogMins()? this.config.getLogMins(): 
util.DEFAULT_LOG_TIME;
+    var paramedicLog = new ParamedicLog(this.config.getPlatformId(), 
this.tempFolder.name, outputDir);
+    paramedicLog.collectLogs(logMins);
+};
+
 var storedCWD =  null;
 
 exports.run = function(paramedicConfig) {

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/utils/index.js
----------------------------------------------------------------------
diff --git a/lib/utils/index.js b/lib/utils/index.js
index 38ad5f4..38bbb80 100644
--- a/lib/utils/index.js
+++ b/lib/utils/index.js
@@ -18,6 +18,7 @@
 */
 
 module.exports = {
-    exec: require('./execWrapper'),
-    logger: require('cordova-common').CordovaLogger.get()
+    exec:       require('./execWrapper'),
+    logger:     require('cordova-common').CordovaLogger.get(),
+    utilities:  require('./utilities')
 };

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/lib/utils/utilities.js
----------------------------------------------------------------------
diff --git a/lib/utils/utilities.js b/lib/utils/utilities.js
new file mode 100644
index 0000000..123a3b2
--- /dev/null
+++ b/lib/utils/utilities.js
@@ -0,0 +1,123 @@
+#!/usr/bin/env node
+
+var shelljs = require('shelljs');
+var verbose = undefined;
+var fs      = require('fs');
+var os      = require("os");
+var util    = require('util');
+var path    = require("path-extra");
+var logger  = require('cordova-common').CordovaLogger.get();
+
+var HEADING_LINE_PATTERN = /List of devices/m;
+var DEVICE_ROW_PATTERN   = /(emulator|device|host)/m;
+
+function isWindows () {
+    return /^win/.test(os.platform());
+}
+
+function countAndroidDevices() {
+    var listCommand = "adb devices";
+
+    logger.info("running:");
+    logger.info("    " + listCommand);
+
+    var numDevices = 0;
+    var result = shelljs.exec(listCommand, {silent: false, async: false});
+    result.output.split('\n').forEach(function (line) {
+        if (!HEADING_LINE_PATTERN.test(line) && DEVICE_ROW_PATTERN.test(line)) 
{
+            numDevices += 1;
+        }
+    });
+    return numDevices;
+}
+
+function secToMin (seconds) {
+    return Math.ceil(seconds / 60);
+}
+
+function getSimulatorsFolder() {
+    var simulatorsFolderPath = path.join(path.homedir(), "Library", 
"Developer", "CoreSimulator", "Devices");
+    return simulatorsFolderPath;
+}
+
+function getSimId() {
+    var findSimCommand = "cordova run --list --emulator | grep ^iPhone | tail 
-n1";
+
+    logger.info("running:");
+    logger.info("    " + findSimCommand);
+
+    var findSimResult = shelljs.exec(findSimCommand, {silent: true, async: 
false});
+
+    if (findSimResult.code > 0) {
+        logger.error("Failed to find simulator we deployed to");
+        return;
+    }
+
+    var split = findSimResult.output.split(", ");
+
+    // Format of the output is "iPhone-6s-Plus, 9.1"
+    // Extract the device name and the version number
+    var device = split[0].replace(/-/g, " ").trim();
+    var version = split[1].trim();
+
+    // Next, figure out the ID of the simulator we found
+    var instrCommand = "instruments -s devices | grep ^iPhone";
+    logger.info("running:");
+    logger.info("    " + instrCommand);
+
+    var instrResult = shelljs.exec(instrCommand, {silent: true, async: false});
+
+    if (instrResult.code > 0) {
+        logger.error("Failed to get the list of simulators");
+        return;
+    }
+
+    // This matches <device> (<version>) [<simulator-id>]
+    var simIdRegex = /^([a-zA-Z\d ]+) \(([\d.]+)\) \[([a-zA-Z\d\-]*)\].*$/;
+
+    var simId = null;
+    var lines = instrResult.output.split(/\n/);
+    lines.forEach(function(line) {
+        var simIdMatch = simIdRegex.exec(line);
+        if (simIdMatch && simIdMatch.length === 4 && simIdMatch[1] === device 
&& simIdMatch[2] === version) {
+            simId = encodeURIComponent(simIdMatch[3]);
+        }
+    });
+
+    return simId;
+}
+
+function doesFileExist(filePath) {
+    var fileExists = false;
+    try {
+        stats = fs.statSync(filePath);
+        fileExists = true;
+    } catch (e) {
+        fileExists = false;
+    }
+    return fileExists;
+}
+
+function getSqlite3InsertionCommand(destinationTCCFile, service, appName) {
+    return util.format( 'sqlite3 %s "insert into access'
+                      + '(service, client, client_type, allowed, prompt_count, 
csreq) values(\'%s\', \'%s\', '
+                      + '0,1,1,NULL)"', destinationTCCFile, service, appName);
+}
+
+module.exports = {
+    ANDROID:    "android",
+    IOS:        "ios",
+    WINDOWS:    "windows",
+    PARAMEDIC_DEFAULT_APP_NAME: "io.cordova.hellocordova",
+
+    DEFAULT_LOG_TIME: 15,
+    DEFAULT_LOG_TIME_ADDITIONAL: 2,
+
+    secToMin: secToMin,
+    isWindows:  isWindows,
+    countAndroidDevices: countAndroidDevices,
+    getSimulatorsFolder: getSimulatorsFolder,
+    getSimId: getSimId,
+    doesFileExist: doesFileExist,
+    getSqlite3InsertionCommand: getSqlite3InsertionCommand
+};

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/main.js
----------------------------------------------------------------------
diff --git a/main.js b/main.js
index db49a49..db66059 100755
--- a/main.js
+++ b/main.js
@@ -1,11 +1,11 @@
 #!/usr/bin/env node
 
-var parseArgs = require('minimist'),
-    path = require('path'),
-    paramedic = require('./lib/paramedic'),
-    ParamedicConfig = require('./lib/ParamedicConfig');
+var parseArgs       = require('minimist');
+var path            = require('path');
+var paramedic       = require('./lib/paramedic');
+var ParamedicConfig = require('./lib/ParamedicConfig');
 
-var USAGE = "Error missing args. \n" +
+var USAGE           = "Error missing args. \n" +
     "cordova-paramedic --platform PLATFORM --plugin PATH [--justbuild 
--timeout MSECS --startport PORTNUM --endport PORTNUM --browserify]\n" +
     "`PLATFORM` : the platform id. Currently supports 'ios', 'browser', 
'windows', 'android', 'wp8'.\n" +
                     "\tPath to platform can be specified as link to git repo 
like:\n" +
@@ -24,8 +24,10 @@ var USAGE = "Error missing args. \n" +
     "--verbose : (optional) verbose mode. Display more information output\n" +
     "--useTunnel : (optional) use tunneling instead of local address. default 
is false\n" +
     "--config : (optional) read configuration from paramedic configuration 
file\n" +
-    "--reportSavePath: (optional) path to save Junit results file\n" +
-    "--cleanUpAfterRun: (optional) cleans up the application after the run.";
+    "--outputDir: (optional) path to save Junit results file & Device logs\n" +
+    "--cleanUpAfterRun: (optional) cleans up the application after the run\n" +
+    "--logMins: (optional) Windows only - specifies number of minutes to get 
logs\n" +
+    "--tccDb: (optional) iOS only - specifies the path for the TCC.db file to 
be copied.";
 
 var argv = parseArgs(process.argv.slice(2));
 var pathToParamedicConfig = argv.config && path.resolve(argv.config);
@@ -37,6 +39,30 @@ if (pathToParamedicConfig || // --config
         ParamedicConfig.parseFromFile(pathToParamedicConfig):
         ParamedicConfig.parseFromArguments(argv);
 
+    if(argv.plugin) {
+        paramedicConfig.setPlugins(argv.plugin);
+    }
+
+    if(argv.outputDir) {
+        paramedicConfig.setOutputDir(argv.outputDir);
+    }
+
+    if(argv.logMins) {
+        paramedicConfig.setLogMins(argv.logMins);
+    }
+
+    if(argv.tccDb){
+        paramedicConfig.setTccDb(argv.tccDb);
+    }
+
+    if(argv.platform) {
+        paramedicConfig.setPlatform(argv.platform);
+    }
+
+    if(argv.action) {
+        paramedicConfig.setAction(argv.action);
+    }
+
     paramedic.run(paramedicConfig)
     .catch(function (error) {
         console.error(error.message);

http://git-wip-us.apache.org/repos/asf/cordova-paramedic/blob/739c4326/package.json
----------------------------------------------------------------------
diff --git a/package.json b/package.json
index 011f5d1..d47b52c 100644
--- a/package.json
+++ b/package.json
@@ -39,7 +39,8 @@
     "shelljs": "~0.3.0",
     "socket.io": "^1.4.5",
     "tcp-port-used": "^0.1.2",
-    "tmp": "0.0.25"
+    "tmp": "0.0.25",
+    "path-extra": "^3.0.0"
   },
   "devDependencies": {
     "jasmine-node": "~1",


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscr...@cordova.apache.org
For additional commands, e-mail: commits-h...@cordova.apache.org

Reply via email to