diff --git a/.gitignore b/.gitignore index ddc017468..385096ae7 100644 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ dist/ !css-value/**/*.* !fetch/**/*.* !apps/TelerikNEXT/lib/**/*.* +!build/*.* CrossPlatformModules.sln.ide/ *.suo CrossPlatformModules.suo @@ -27,3 +28,6 @@ obj/ .baseDir.ts .ctags-exclude tags + +TestRunResult.txt +.testsapprun diff --git a/apps/tests/app/mainPage.ts b/apps/tests/app/mainPage.ts index d7be1412c..d204b2b47 100644 --- a/apps/tests/app/mainPage.ts +++ b/apps/tests/app/mainPage.ts @@ -1,50 +1,23 @@ -import pages = require("ui/page"); -import gridModule = require("ui/layouts/grid-layout"); +import {Page} from "ui/page"; +import * as trace from "trace"; import tests = require("../testRunner"); -import bm = require("ui/button"); -import trace = require("trace"); -import textViewModule = require("ui/text-view"); -class MyTraceWriter implements trace.TraceWriter { - public write(message: any, category: string) { - if (textView && message && message.toLowerCase().indexOf("failed") !== -1) { - if (textView.android) { - textView.text = message + "\r\n" + textView.text; - } - else { - textView.text = message + "\n" + textView.text; - } - } - } -} - -trace.addWriter(new MyTraceWriter()); trace.enable(); trace.addCategories(trace.categories.Test + "," + trace.categories.Error); -var textView = new textViewModule.TextView(); -textView.editable = false; -textView.style.fontSize = 8; +let started = false; +let page = new Page(); + +page.on(Page.navigatedToEvent, function () { + if (!started) { + started = true; + setTimeout(function () { + tests.runAll(); + }, 10); + } +}); export function createPage() { - var button = new bm.Button(); - button.text = "Run Tests"; - button.on(bm.Button.tapEvent, function () { - tests.runAll(); - }); - - var grid = new gridModule.GridLayout(); - - grid.addRow(new gridModule.ItemSpec(1, gridModule.GridUnitType.auto)); - grid.addRow(new gridModule.ItemSpec()); - - gridModule.GridLayout.setRow(textView, 1); - - grid.addChild(button); - grid.addChild(textView); - - var page = new pages.Page(); - page.content = grid; return page; } -//export var Page = page; + diff --git a/build/run-testsapp.grunt.js b/build/run-testsapp.grunt.js new file mode 100644 index 000000000..86d85a311 --- /dev/null +++ b/build/run-testsapp.grunt.js @@ -0,0 +1,301 @@ +module.exports = { + + run: function(grunt) { + var pathModule = require("path"); + + var modulesPackageConfig = grunt.file.readJSON('package.json'); + + //Construct and validate the arguments + var args = { + platform: grunt.option("platform"), + modulesPath: grunt.option("modulesPath"), + tnsPath: grunt.option("tnsPath"), + emulatorProcessIdentifier: grunt.option("emuPId"), + emuAvdName: grunt.option("avd"), + outFile: grunt.option("logFilePath"), + runtimePath: grunt.option("runtimePath"), + showEmu: grunt.option("showEmu") + }; + + (function validateInput(){ + if (!(/^(Android|iOS)$/).test(args.platform)) { + throw new Error("Invalid target platform specified! Use --platform=Android|iOS"); + } + + if (args.platform === "Android") { + if (!args.emulatorProcessIdentifier) { + throw new Error("Please, specify an identifier of the emulator process so that it can be stopped (--emuPId=...). Too many emulators started might cause machine overload"); + } + if (!args.emuAvdName) { + throw new Error("Please, specify the name of the AVD to start (--avd=...)."); + } + } + }()); + + var localCfg = { + tnsPath: args.tnsPath || "tns", + emulatorProcessIdentifier: args.emulatorProcessIdentifier, + modulesPath: args.modulesPath || "./bin/dist/tns-core-modules-" + modulesPackageConfig.version + ".tgz", + emuAvdName: args.emuAvdName, + outFile: args.outFile || "./TestRunResult.txt", + frameworkArgument: args.runtimePath ? " --frameworkPath=" + args.runtimePath : "", + showEmu: args.showEmu || false, + + workingDir:".testsapprun", + testsAppName:"TestsApp", + applicationDir: pathModule.join(".testsapprun", "TestsApp"), + appDir: pathModule.join(".testsapprun", "TestsApp", "app"), + pathToApk: "./platforms/android/build/outputs/apk/TestsApp-debug.apk", + pathToApp: "./platforms/ios/build/emulator/TestsApp.app", + deployedAppName:"org.nativescript.TestsApp", + mainActivityName:"com.tns.NativeScriptActivity", + pathToCompiledTests: "bin/dist/apps/tests", + simulatorSysLog: pathModule.join(process.env.HOME, "Library/Logs/CoreSimulator", args.emuAvdName, "/system.log"), + platform: args.platform + } + + grunt.initConfig({ + clean: { + workingDir: { + src: localCfg.workingDir + }, + originalAppDir: { + src: [ + localCfg.appDir + "/*", + "!" + pathModule.join(localCfg.appDir, "App_Resources") + "" + ] + }, + modules: { + src: pathModule.join(localCfg.applicationDir, "node_modules", "tns-core-modules") + }, + tempExtractedModules: { + src: pathModule.join(localCfg.applicationDir, "node_modules", "package") + }, + simulatorLog: { + src: localCfg.simulatorSysLog, + options: { + force: true + } + } + }, + mkdir: { + workingDir: { + options: { + create: [localCfg.workingDir], + mode: 0700 + } + } + }, + copy: { + testsAppToRunDir: { + src: "**/*.*", + dest: localCfg.appDir, + cwd: localCfg.pathToCompiledTests, + expand: true + }, + modulesToDir: { + expand: true, + src: "**/*.*", + cwd: pathModule.join(localCfg.applicationDir, "node_modules", "package"), + dest: pathModule.join(localCfg.applicationDir, "node_modules", "tns-core-modules") + }, + addAndroidPermissions: { + src: "AndroidManifest.xml", + dest: localCfg.applicationDir + "/platforms/android/src/main/", + cwd: localCfg.applicationDir + "/platforms/android/src/main", + expand: true, + options: { + process: function(content, srcPath) { + var newContent = content; + + var internetPermissionFinder = /((\s*)]*android\.permission\.INTERNET[^>]*>)/; + + if (!/uses-permission[^>]*android\.permission\.ACCESS_NETWORK_STATE/.test(content)) { + newContent = newContent.replace(internetPermissionFinder, "$1$2"); + } + if (!/uses-permission[^>]*android\.permission\.ACCESS_FINE_LOCATION/.test(content)) { + newContent = newContent.replace(internetPermissionFinder, "$1$2"); + } + return newContent; + } + } + }, + addiOSPermissions: { + src: localCfg.testsAppName + "-Info.plist", + dest: pathModule.join(localCfg.applicationDir,"/platforms/ios/", localCfg.testsAppName) + "/", + cwd: pathModule.join(localCfg.applicationDir,"/platforms/ios/", localCfg.testsAppName), + expand: true, + options: { + process: function(content, srcPath) { + var newContent = content; + + var lastDictLocator = /(<\/dict>\s*<\/plist>)$/gm; + + if (!/NSAppTransportSecurity/.test(content)) { + newContent = newContent.replace(lastDictLocator, "NSAppTransportSecurity\n$1"); + } + if (!/NSAllowsArbitraryLoads/.test(content)) { + newContent = newContent.replace(lastDictLocator, "\nNSAllowsArbitraryLoads\n\n\n$1"); + } + return newContent; + } + } + }, + simulatorLog: { + src: localCfg.simulatorSysLog, + dest: localCfg.outFile + } + }, + exec: { + killAndroidEmulator: { + cmd: "pkill '" + localCfg.emulatorProcessIdentifier + "'", + exitCode: [0, 1] + }, + killiOSEmulator: { + cmd: "pkill Simulator", + exitCode: [0, 1] + }, + createApp: { + cmd: localCfg.tnsPath + " create " + localCfg.testsAppName, + cwd: localCfg.workingDir + }, + addPlatform: { + cmd: "tns platform add " + localCfg.platform.toLowerCase() + " " + localCfg.frameworkArgument, + cwd: localCfg.applicationDir + }, + restartAdb: { + cmd: "adb kill-server && adb start-server" + }, + uninstallExistingAndroidApp: { + cmd: "adb uninstall " + localCfg.deployedAppName + }, + installNewAndroidApp: { + cmd: "adb install " + localCfg.pathToApk, + cwd: localCfg.applicationDir + }, + startAndroidEmulator: { + cmd: "emulator -avd " + localCfg.emuAvdName + " -no-audio " + (args.showEmu ? "" : "-no-window") + "&" + }, + startAndroidApp: { + cmd: "adb shell am start -n " + localCfg.deployedAppName + "/" + localCfg.mainActivityName + }, + uninstallExistingiOSApp: { + cmd: "xcrun simctl uninstall " + localCfg.emuAvdName + " org.nativescript." + localCfg.testsAppName, + cwd: localCfg.applicationDir + }, + installNewiOSApp: { + cmd: "xcrun simctl install " + localCfg.emuAvdName + " " + localCfg.pathToApp, + cwd: localCfg.applicationDir + }, + startiOSApp: { + cmd: "xcrun simctl launch " + localCfg.emuAvdName + " org.nativescript." + localCfg.testsAppName + }, + }, + untar: { + modules: { + src: localCfg.modulesPath, + dest: pathModule.join(localCfg.applicationDir, "node_modules") + } + }, + shell: { + collectAndroidLog: { + command: "./expect.exp " + "'adb logcat' " + localCfg.outFile, + options: { + execOptions: { + maxBuffer: Infinity + } + } + }, + waitiOSLogCompletion: { + command: "./expect.exp " + "'tail -f " + localCfg.simulatorSysLog + "' " + localCfg.outFile, + options: { + execOptions: { + maxBuffer: Infinity + } + } + }, + startiOSSimulator: { + command: "xcrun instruments -w " + localCfg.emuAvdName, + options: { + failOnError: false + }, + }, + buildApp: { + command: "tns build " + localCfg.platform.toLowerCase(), + options: { + execOptions: { + maxBuffer: Infinity, + cwd: localCfg.applicationDir + } + } + }, + } + }); + + grunt.loadNpmTasks("grunt-shell"); + grunt.loadNpmTasks("grunt-exec"); + grunt.loadNpmTasks("grunt-mkdir"); + grunt.loadNpmTasks("grunt-contrib-clean"); + grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-untar"); + + var getPlatformSpecificTask = function(templatedTaskName) { + return templatedTaskName.replace(/\{platform\}/, localCfg.platform); + } + + grunt.registerTask("startEmulatorAndroid", [ + getPlatformSpecificTask("exec:startAndroidEmulator"), + ]); + + grunt.registerTask("startEmulatoriOS", [ + getPlatformSpecificTask("shell:startiOSSimulator"), + ]); + + grunt.registerTask("collectLogAndroid", [ + "shell:collectAndroidLog" + ]); + + grunt.registerTask("collectLogiOS", [ + "shell:waitiOSLogCompletion", + "copy:simulatorLog" + ]); + + grunt.registerTask("doPostPlatformAddAndroid", [ + "exec:restartAdb" + ]); + + grunt.registerTask("doPostPlatformAddiOS", [ + "clean:simulatorLog" + ]); + + +//xcrun instruments -s + grunt.registerTask("testsapp", [ + "clean:workingDir", + "mkdir:workingDir", + getPlatformSpecificTask("exec:kill{platform}Emulator"), + getPlatformSpecificTask("startEmulator{platform}"), + + "exec:createApp", + "clean:originalAppDir", + "copy:testsAppToRunDir", + "clean:modules", + "untar:modules", + "copy:modulesToDir", + "clean:tempExtractedModules", + + "exec:addPlatform", + getPlatformSpecificTask("copy:add{platform}Permissions"), + "shell:buildApp", + getPlatformSpecificTask("doPostPlatformAdd{platform}"), + + getPlatformSpecificTask("exec:uninstallExisting{platform}App"), + getPlatformSpecificTask("exec:installNew{platform}App"), + getPlatformSpecificTask("exec:start{platform}App"), + getPlatformSpecificTask("collectLog{platform}"), + +// getPlatformSpecificTask("exec:kill{platform}Emulator"), +// "clean:workingDir" + ]); + } +} diff --git a/expect.exp b/expect.exp new file mode 100755 index 000000000..4cbba512e --- /dev/null +++ b/expect.exp @@ -0,0 +1,20 @@ +#! /usr/bin/expect + +#exp_internal 1 + +#set timeout 600 + +#spawn grunt +#expect "TypeScript compilation complete" +#send \003 + + +set cmd [lindex $argv 0]; +set outfile [lindex $argv 1]; + +set timeout 600 +#spawn (adb logcat | tee ./__TESTRESULT__.txt) +log_file -noappend $outfile +eval spawn $cmd +expect "=== ALL TESTS COMPLETE ===" +send \003 diff --git a/gruntfile.js b/gruntfile.js index dae465869..42cd5e013 100644 --- a/gruntfile.js +++ b/gruntfile.js @@ -1,560 +1,567 @@ module.exports = function(grunt) { - var fs=require("fs"); - var pathModule=require("path"); - var filterTypeScriptFiles = function(content, srcPath) { - var matchRule = /^.*@private/ig; - if (matchRule.test(content)) - { - return false; - } - var processed = content; - processed = processed.replace(/\/\/[\/\s]*@private((.|\s)*?)\/\/[\/\s]*@endprivate/gm, ""); - return processed; - }; + if (grunt.cli.tasks.indexOf("testsapp") >= 0) { + var tsTester = require("./build/run-testsapp.grunt.js"); + tsTester.run(grunt); + } else { - var updatePackageDef = function(content, update) - { - var contentAsObject = JSON.parse(content); - update(contentAsObject); - return JSON.stringify(contentAsObject, null, "\t"); - } - var updateModulesPackageDef = function(content, srcPath) { - return updatePackageDef(content, function(contentAsObject) { - contentAsObject.version = localCfg.packageVersion; - if (localCfg.commitSHA) { - contentAsObject.repository.url += "/commit/" + localCfg.commitSHA; - } - }); - }; + var fs=require("fs"); + var pathModule=require("path"); - var updateAppPackageDef = function(content, srcPath) { - var currentAppName = grunt.task.current.data.appName; - return updatePackageDef(content, function(contentAsObject) { - contentAsObject.version = localCfg.packageVersion; - contentAsObject.author = "Telerik "; - var specificKeywords = ["telerik", "mobile", "nativescript", "{N}", "tns", "appbuilder"]; - if (currentAppName.indexOf("template-") == 0) { - var templateName = currentAppName.substring("template-".length); - contentAsObject.name = "tns-" + currentAppName; - contentAsObject.description = "Nativescript " + templateName + " project template"; - specificKeywords.push("template"); - } - else { - contentAsObject.name = "tns-samples-" + currentAppName; - contentAsObject.description = "Nativescript " + currentAppName + " sample application"; - specificKeywords.push("sample"); - } - contentAsObject.license = "BSD"; - addKeywords(contentAsObject, specificKeywords); - - if (!contentAsObject.repository) { - contentAsObject.repository = {}; - } - if (!contentAsObject.repository.url) { - contentAsObject.repository.url = localCfg.mainPackageContent.repository.url; - } - if (localCfg.commitSHA) { - contentAsObject.repository.url += "/commit/" + localCfg.commitSHA; - } - }); - }; - - var addKeywords = function(packageObject, newKeywords) { - if (!packageObject.keywords) { - packageObject.keywords = newKeywords; - return; - } - - if (typeof(packageObject.keywords) == "string") { - packageObject.keywords = packageObject.keywords.split(" "); - } - packageObject.keywords = packageObject.keywords.concat(newKeywords); - }; - - var updateDefinitionsPackageDef = function(content, srcPath) { - return updatePackageDef(content, function(contentAsObject) { - contentAsObject.version = localCfg.packageVersion; - contentAsObject.name = "tns-definitions"; - contentAsObject.description = "NativeScript Module definitions"; - contentAsObject.license = "Apache-2.0"; - if (localCfg.commitSHA) { - contentAsObject.repository.url += "/commit/" + localCfg.commitSHA; - } - }); - }; - - var getCommitSha = function() { - if (process.env.GIT_COMMIT) { - return process.env.GIT_COMMIT; - } - return ""; - }; - - var assignGitSHA = function(err, stdout, stderr, cb) { - if (!localCfg.commitSHA) { - localCfg.commitSHA = stdout.replace("\n", ""); - } - cb(); - }; - - var getPackageVersion = function() { - var buildVersion = process.env.PACKAGE_VERSION; - if (!buildVersion) { - return localCfg.mainPackageContent.version; - } - return localCfg.mainPackageContent.version + "-" + buildVersion; - }; - - var processAppFile = function(content, srcPath) { - return content; - }; - - var getSubDirs = function(dir) { - var allObjects = fs.readdirSync(dir); - var allDirs = []; - for (var i=0; i/", - cwd: localCfg.srcDir - }, - license: { - expand: true, - src: [ - "./LICENSE", - ], - dest: "<%= localCfg.outModulesDir %>/", - cwd: localCfg.srcDir - }, - appLicense: { - expand: true, - src: ["./LICENSE"], - cwd: localCfg.srcAppsDir, - dest: "__dummy__" - }, - definitionFiles: { - src: [ - localCfg.srcDir + "/**/*.d.ts", - pathModule.join(localCfg.srcDir, "LICENSE"), - //Exclude the d.ts files in the apps folder - these are part of the apps and are already packed there! - "!" + localCfg.srcDir + "/apps/**" - ].concat(localCfg.defaultExcludes).concat(localCfg.excludedModules), - dest: localCfg.outDefinitionsDir + "/", - expand: true, - options: { - process: filterTypeScriptFiles - } - }, - modulesPackageDef: { - expand: true, - src: localCfg.packageJsonFilePath, - dest: localCfg.outModulesDir + "/", - options: { - process: updateModulesPackageDef - } - }, - definitionsPackageDef: { - src: localCfg.packageJsonFilePath, - dest: localCfg.outDefinitionsDir + "/", - options: { - process: updateDefinitionsPackageDef - } - }, - appPackageDef: { - expand: true, - flatten: true, - src: "__app_package_json", - dest: "__dummy__", - options: { - process: updateAppPackageDef - } - }, - childPackageFiles: { - expand: true, - src: [ - localCfg.srcDir + "/**/package.json", - "!./package.json", - "!./Deploy/**/*.*", - "!./bin/**/*.*", - "!./Tests/**/*.*", - "!" + localCfg.outDir + "/**/*.*" - ].concat(localCfg.excludedModules), - dest: localCfg.outModulesDir + "/" - }, - rawAppsFiles: { - expand: true, - src: [ - "**/*.*", - "**/*", - "!**/*.map", - "!**/*.ts" - ], - dest: localCfg.outAppsDir, - cwd: localCfg.srcAppsDir, - dot: true - }, - readyAppFiles: { - expand: true, - src: ["./**/*.*"], - dest: localCfg.outAppsDir + "/", - cwd: localCfg.outModulesDir + "/apps/", - options: { - process: processAppFile - } - }, - readyTsAppFiles: { - expand: true, - src: ["./**/*.*", "!./**/*.map"], - dest: localCfg.outTsAppsDir + "/", - cwd: localCfg.srcAppsDir - }, - readyPackages: { - expand: true, - src: ["./**/*.tgz"], - dest: localCfg.outDir + "/", - cwd: localCfg.outDir, - flatten: true - } - }, - ts: { - build: { - src: localCfg.typeScriptSrc, - outDir: localCfg.outModulesDir, - options: { - fast: 'never', - module: "commonjs", - target: "es5", - sourceMap: false, - declaration: false, - removeComments: "<%= !grunt.option('leavecomments') || '' %>", - compiler: "node_modules/typescript/bin/tsc", - noEmitOnError: true, - experimentalDecorators: true, - noEmitHelpers: true - } - }, - buildNodeTests: { - src: [ - 'js-libs/easysax/**/*.ts', - 'xml/**/*.ts', - 'node-tests/**/*.ts', - ], - outDir: localCfg.outModulesDir, - options: { - fast: 'never', - module: "commonjs", - target: "es5", - sourceMap: false, - declaration: false, - removeComments: "<%= !grunt.option('leavecomments') || '' %>", - compiler: "node_modules/typescript/bin/tsc", - noEmitOnError: true - } - } - }, - tslint: { - build: { - files: { - src: localCfg.typeScriptSrcForTsLint + grunt.initConfig({ + localCfg : localCfg, + pkg: grunt.file.readJSON('package.json'), + clean: { + build: { + src: [localCfg.outDir] }, - options: { + typeScriptLeftovers: { + expand: true, + src: [ + "./.baseDir.*", + "./_references.js", + "./**/*.map" + ], + cwd: localCfg.outModulesDir + }, + nodeTests: { + src: localCfg.nodeTestsDir, + }, + readyAppFiles: { + src: [localCfg.outModulesDir + "/apps/**"] + } + }, + copy: { + jsLibs: { + expand: true, + src: [ + "./js-libs/**/*.js", + "./fetch/**/*.js", + "./css/**/*.js", + "./css-value/**/*.js", + ], + dest: "<%= localCfg.outModulesDir %>/", + cwd: localCfg.srcDir + }, + license: { + expand: true, + src: [ + "./LICENSE", + ], + dest: "<%= localCfg.outModulesDir %>/", + cwd: localCfg.srcDir + }, + appLicense: { + expand: true, + src: ["./LICENSE"], + cwd: localCfg.srcAppsDir, + dest: "__dummy__" + }, + definitionFiles: { + src: [ + localCfg.srcDir + "/**/*.d.ts", + pathModule.join(localCfg.srcDir, "LICENSE"), + //Exclude the d.ts files in the apps folder - these are part of the apps and are already packed there! + "!" + localCfg.srcDir + "/apps/**" + ].concat(localCfg.defaultExcludes).concat(localCfg.excludedModules), + dest: localCfg.outDefinitionsDir + "/", + expand: true, + options: { + process: filterTypeScriptFiles + } + }, + modulesPackageDef: { + expand: true, + src: localCfg.packageJsonFilePath, + dest: localCfg.outModulesDir + "/", + options: { + process: updateModulesPackageDef + } + }, + definitionsPackageDef: { + src: localCfg.packageJsonFilePath, + dest: localCfg.outDefinitionsDir + "/", + options: { + process: updateDefinitionsPackageDef + } + }, + appPackageDef: { + expand: true, + flatten: true, + src: "__app_package_json", + dest: "__dummy__", + options: { + process: updateAppPackageDef + } + }, + childPackageFiles: { + expand: true, + src: [ + localCfg.srcDir + "/**/package.json", + "!./package.json", + "!./Deploy/**/*.*", + "!./bin/**/*.*", + "!./Tests/**/*.*", + "!" + localCfg.outDir + "/**/*.*" + ].concat(localCfg.excludedModules), + dest: localCfg.outModulesDir + "/" + }, + rawAppsFiles: { + expand: true, + src: [ + "**/*.*", + "**/*", + "!**/*.map", + "!**/*.ts" + ], + dest: localCfg.outAppsDir, + cwd: localCfg.srcAppsDir, + dot: true + }, + readyAppFiles: { + expand: true, + src: ["./**/*.*"], + dest: localCfg.outAppsDir + "/", + cwd: localCfg.outModulesDir + "/apps/", + options: { + process: processAppFile + } + }, + readyTsAppFiles: { + expand: true, + src: ["./**/*.*", "!./**/*.map"], + dest: localCfg.outTsAppsDir + "/", + cwd: localCfg.srcAppsDir + }, + readyPackages: { + expand: true, + src: ["./**/*.tgz"], + dest: localCfg.outDir + "/", + cwd: localCfg.outDir, + flatten: true + } + }, + ts: { + build: { + src: localCfg.typeScriptSrc, + outDir: localCfg.outModulesDir, + options: { + fast: 'never', + module: "commonjs", + target: "es5", + sourceMap: false, + declaration: false, + removeComments: "<%= !grunt.option('leavecomments') || '' %>", + compiler: "node_modules/typescript/bin/tsc", + noEmitOnError: true, + experimentalDecorators: true, + noEmitHelpers: true + } + }, + buildNodeTests: { + src: [ + 'js-libs/easysax/**/*.ts', + 'xml/**/*.ts', + 'node-tests/**/*.ts', + ], + outDir: localCfg.outModulesDir, + options: { + fast: 'never', + module: "commonjs", + target: "es5", + sourceMap: false, + declaration: false, + removeComments: "<%= !grunt.option('leavecomments') || '' %>", + compiler: "node_modules/typescript/bin/tsc", + noEmitOnError: true + } + } + }, + tslint: { + build: { + files: { + src: localCfg.typeScriptSrcForTsLint + }, + options: { configuration: grunt.file.readJSON("./build/tslint.json") - } - } - }, - exec: { - packModules: { - cmd: "npm pack", - cwd: localCfg.outModulesDir + "/" - }, - packDefinitions: { - cmd: "npm pack", - cwd: localCfg.outDefinitionsDir + "/" - }, - packApp: { - cmd: "npm pack", - cwd: "__dummy__" - }, - mochaNode: { - cmd: "grunt simplemocha:node" - } - }, - multidest: { - copyLicenseFiles: { - tasks: ["copy:appLicense"], - dest: function() { - var apps = getSubDirs(localCfg.srcAppsDir); - var targetDirs = []; - apps.forEach(function(item){ - targetDirs.push(pathModule.join(localCfg.outAppsDir, item.name)); - targetDirs.push(pathModule.join(localCfg.outTsAppsDir, item.name)); - }); - return targetDirs; - }() - } - }, - shell: { - getGitSHA: { - command: "git rev-parse HEAD", - options: { - callback: assignGitSHA + } } }, - }, - simplemocha: { - node: { - src: localCfg.nodeTestsDir + '/**/*.js' + exec: { + packModules: { + cmd: "npm pack", + cwd: localCfg.outModulesDir + "/" + }, + packDefinitions: { + cmd: "npm pack", + cwd: localCfg.outDefinitionsDir + "/" + }, + packApp: { + cmd: "npm pack", + cwd: "__dummy__" + }, + mochaNode: { + cmd: "grunt simplemocha:node" + } + }, + multidest: { + copyLicenseFiles: { + tasks: ["copy:appLicense"], + dest: function() { + var apps = getSubDirs(localCfg.srcAppsDir); + var targetDirs = []; + apps.forEach(function(item){ + targetDirs.push(pathModule.join(localCfg.outAppsDir, item.name)); + targetDirs.push(pathModule.join(localCfg.outTsAppsDir, item.name)); + }); + return targetDirs; + }() + } + }, + shell: { + getGitSHA: { + command: "git rev-parse HEAD", + options: { + callback: assignGitSHA + } + }, + }, + simplemocha: { + node: { + src: localCfg.nodeTestsDir + '/**/*.js' + } + }, + env: { + nodeTests: { + NODE_PATH: localCfg.outModulesDir, + } } - }, - env: { - nodeTests: { - NODE_PATH: localCfg.outModulesDir, + }); + + grunt.loadNpmTasks("grunt-ts"); + grunt.loadNpmTasks("grunt-contrib-clean"); + grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-exec"); + grunt.loadNpmTasks("grunt-tslint"); + grunt.loadNpmTasks("grunt-multi-dest"); + grunt.loadNpmTasks("grunt-shell"); + grunt.loadNpmTasks("grunt-env"); + grunt.loadNpmTasks("grunt-simple-mocha"); + + var cloneTasks = function(originalTasks, taskNameSuffix) { + var clonedTasks = []; + for(var i=0; iAs this is a [grunt](http://gruntjs.com/) script, the arguments are passed + the grunt way (`--argName=argValue`) + +- `platform`: The platform to run the tests application on: iOS or Android +- `showEmu`: [Optional] Specifies whether the emulator should get launched +in a window or headless mode. Defaults to `false`. +- `modulesPath`: [Optional] The path to the tns-core-modules npm package +to be tested. Defaults to the npm package, located in the current +`bin/dist/` folder. The modules must have been built before that. +- `tnsPath`: [Optional] The path to the NativeScript executable. If not +found, the globally installed `tns` gets called. +- `emuPId`: The ID of the emulator process. This one is used to refresh the +emulator process, as the emulator sometimes hangs. +- `avd`: The name of the Android Virtual Device or the iOS simulator GUID +to be started to run the tests. +- `logFilePath`: [Optional] The path to the file, which the test app run +log will get saved to. Defaults to "./TestRunResult.txt". +- `runtimePath`: [Optional] The path to a custom iOS or Android Runtime +package to have the tests run onto. If not specified, the newest available +build on [npmjs.com](http://npmjs.com) - +[tns-ios](https://www.npmjs.com/package/tns-ios) or +[tns-android](https://www.npmjs.com/package/tns-android). + +# Sample run: +``` +grunt testsapp --platform=Android [--tnsPath="tns"] --emuPId=".*emulator64-x86" +--avd="Api19" [--logFilePath="./TestRunResult.txt"] [--androidRuntimePath="./tns-android.tgz"] --showEmu=true +```