diff --git a/gulpfile.js b/gulpfile.js index 6f6fdce..dc86db4 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -121,7 +121,20 @@ function runTests(callback, options) { // pass arguments from command line // the fourth argument is the first argument after the task name for (var i = 3; i < process.argv.length; i++) { - args.push(process.argv[i]); + if (process.argv[i] === "--report") { + // Set up the mocha junit reporter. + args.push("--reporter"); + args.push("mocha-junit-reporter"); + + // Set the mocha reporter to the correct output file. + args.push("--reporter-options"); + var filename = "./test-results.xml"; + if (options.android && !options.ios) filename = "./test-android.xml"; + else if (options.ios && !options.android) filename = "./test-ios.xml"; + args.push("mochaFile=" + filename); + // Delete previous test result file so TFS doesn't read the old file if the tests exit before saving + del(filename); + } else args.push(process.argv[i]); } execCommand(command, args, callback); diff --git a/test/test.ts b/test/test.ts index 5b75189..8002653 100644 --- a/test/test.ts +++ b/test/test.ts @@ -13,13 +13,246 @@ import fs = require("fs"); import mkdirp = require("mkdirp"); import path = require("path"); -import { Platform, PluginTestingFramework, ProjectManager, ServerUtil } from "code-push-plugin-testing-framework"; +import { Platform, PluginTestingFramework, ProjectManager, ServerUtil, TestUtil } from "code-push-plugin-testing-framework"; import Q = require("q"); var del = require("del"); +////////////////////////////////////////////////////////////////////////////////////////// +// Create the platforms to run the tests on. + +interface RNPlatform { + /** + * Returns the name of the bundle to be created for this platform. + */ + getBundleName(): string; + + /** + * Returns whether or not this platform supports diffs. + */ + isDiffsSupported(): boolean; + + /** + * Returns the path to the binary of the given project on this platform. + */ + getBinaryPath(projectDirectory: string): string; + + /** + * Installs the platform on the given project. + */ + installPlatform(projectDirectory: string): Q.Promise; + + /** + * Installs the binary of the given project on this platform. + */ + installApp(projectDirectory: string): Q.Promise; + + /** + * Builds the binary of the project on this platform. + */ + buildApp(projectDirectory: string): Q.Promise; +} + +class RNAndroid extends Platform.Android implements RNPlatform { + constructor() { + super(new Platform.AndroidEmulatorManager()); + } + + /** + * Returns the name of the bundle to be created for this platform. + */ + getBundleName(): string { + return "index.android.bundle"; + } + + /** + * Returns whether or not this platform supports diffs. + */ + isDiffsSupported(): boolean { + return false; + } + + /** + * Returns the path to the binary of the given project on this platform. + */ + getBinaryPath(projectDirectory: string): string { + return path.join(projectDirectory, PluginTestingFramework.TestAppName, "android", "app", "build", "outputs", "apk", "app-release-unsigned.apk"); + } + + /** + * Installs the platform on the given project. + */ + installPlatform(projectDirectory: string): Q.Promise { + var innerprojectDirectory: string = path.join(projectDirectory, PluginTestingFramework.TestAppName); + + //// Set up gradle to build CodePush with the app + // Add CodePush to android/app/build.gradle + var buildGradle = path.join(innerprojectDirectory, "android", "app", "build.gradle"); + TestUtil.replaceString(buildGradle, + "apply from: \"../../node_modules/react-native/react.gradle\"", + "apply from: \"../../node_modules/react-native/react.gradle\"\napply from: \"" + path.join(innerprojectDirectory, "node_modules", "react-native-code-push", "android", "codepush.gradle") + "\""); + TestUtil.replaceString(buildGradle, + "compile \"com.facebook.react:react-native:+\"", + "compile \"com.facebook.react:react-native:0.25.+\""); + TestUtil.replaceString(buildGradle, + "// From node_modules", + "\n compile project(':react-native-code-push') // From node_modules"); + // Add CodePush to android/settings.gradle + TestUtil.replaceString(path.join(innerprojectDirectory, "android", "settings.gradle"), + "include ':app'", + "include ':app', ':react-native-code-push'\nproject(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')"); + + //// Set the app version to 1.0.0 instead of 1.0 + // Set the app version to 1.0.0 in android/app/build.gradle + TestUtil.replaceString(buildGradle, "versionName \"1.0\"", "versionName \"1.0.0\""); + // Set the app version to 1.0.0 in AndroidManifest.xml + TestUtil.replaceString(path.join(innerprojectDirectory, "android", "app", "src", "main", "AndroidManifest.xml"), "android:versionName=\"1.0\"", "android:versionName=\"1.0.0\""); + + //// Replace the MainActivity.java with the correct server url and deployment key + var mainActivity = path.join(innerprojectDirectory, "android", "app", "src", "main", "java", "com", "microsoft", "codepush", "test", "MainActivity.java"); + TestUtil.replaceString(mainActivity, TestUtil.CODE_PUSH_TEST_APP_NAME_PLACEHOLDER, PluginTestingFramework.TestAppName); + TestUtil.replaceString(mainActivity, TestUtil.SERVER_URL_PLACEHOLDER, this.getServerUrl()); + TestUtil.replaceString(mainActivity, TestUtil.ANDROID_KEY_PLACEHOLDER, this.getDefaultDeploymentKey()); + + return Q(undefined); + } + + /** + * Installs the binary of the given project on this platform. + */ + installApp(projectDirectory: string): Q.Promise { + var androidDirectory: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "android"); + return TestUtil.getProcessOutput("adb install -r " + this.getBinaryPath(projectDirectory), { cwd: androidDirectory }); + } + + /** + * Builds the binary of the project on this platform. + */ + buildApp(projectDirectory: string): Q.Promise { + // In order to run on Android without the package manager, we must create a release APK and then sign it with the debug certificate. + var androidDirectory: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "android"); + var apkPath = this.getBinaryPath(projectDirectory); + return TestUtil.getProcessOutput("./gradlew assembleRelease --daemon", { cwd: androidDirectory }) + .then(TestUtil.getProcessOutput.bind(undefined, "jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android " + apkPath + " androiddebugkey", { cwd: androidDirectory }, false)); + } +} + +class RNIOS extends Platform.IOS implements RNPlatform { + constructor() { + super(new Platform.IOSEmulatorManager()); + } + + /** + * Returns the name of the bundle to be created for this platform. + */ + getBundleName(): string { + return "main.jsbundle"; + } + + /** + * Returns whether or not this platform supports diffs. + */ + isDiffsSupported(): boolean { + return true; + } + + /** + * Returns the path to the binary of the given project on this platform. + */ + getBinaryPath(projectDirectory: string): string { + return path.join(projectDirectory, PluginTestingFramework.TestAppName, "ios", "build", "Build", "Products", "Release-iphonesimulator", PluginTestingFramework.TestAppName + ".app"); + } + + /** + * Installs the platform on the given project. + */ + installPlatform(projectDirectory: string): Q.Promise { + var iOSProject: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "ios"); + var infoPlistPath: string = path.join(iOSProject, PluginTestingFramework.TestAppName, "Info.plist"); + var appDelegatePath: string = path.join(iOSProject, PluginTestingFramework.TestAppName, "AppDelegate.m"); + // Create and install the Podfile + return TestUtil.getProcessOutput("pod init", { cwd: iOSProject }) + .then(() => { return fs.appendFileSync(path.join(iOSProject, "Podfile"), + "target '" + PluginTestingFramework.TestAppName + "'\n pod 'React', :path => '../node_modules/react-native', :subspecs => [ 'Core', 'RCTImage', 'RCTNetwork', 'RCTText', 'RCTWebSocket', ]\n pod 'CodePush', :path => '../node_modules/react-native-code-push'\n"); }) + // Put the IOS deployment key in the Info.plist + .then(TestUtil.replaceString.bind(undefined, infoPlistPath, + "\n", + "CodePushDeploymentKey\n\t" + this.getDefaultDeploymentKey() + "\n\tCodePushServerURL\n\t" + this.getServerUrl() + "\n\t\n")) + // Add the correct linker flags to the project.pbxproj + .then(TestUtil.replaceString.bind(undefined, path.join(iOSProject, PluginTestingFramework.TestAppName + ".xcodeproj", "project.pbxproj"), + "\"-lc[+][+]\",", "\"-lc++\", \"$(inherited)\"")) + // Install the Pod + .then(TestUtil.getProcessOutput.bind(undefined, "pod install", { cwd: iOSProject })) + // Add the correct bundle identifier to the Info.plist + .then(TestUtil.replaceString.bind(undefined, infoPlistPath, + "org[.]reactjs[.]native[.]example[.][$][(]PRODUCT_NAME:rfc1034identifier[)]", + PluginTestingFramework.TestNamespace)) + // Set the app version to 1.0.0 instead of 1.0 in the Info.plist + .then(TestUtil.replaceString.bind(undefined, infoPlistPath, "1.0", "1.0.0")) + // Fix the linker flag list in project.pbxproj (pod install adds an extra comma) + .then(TestUtil.replaceString.bind(undefined, path.join(iOSProject, PluginTestingFramework.TestAppName + ".xcodeproj", "project.pbxproj"), + "\"[$][(]inherited[)]\",\\s*[)];", "\"$(inherited)\"\n\t\t\t\t);")) + // Copy the AppDelegate.m to the project + .then(TestUtil.copyFile.bind(undefined, + path.join(PluginTestingFramework.templatePath, "ios", PluginTestingFramework.TestAppName, "AppDelegate.m"), + appDelegatePath, true)) + .then(TestUtil.replaceString.bind(undefined, appDelegatePath, TestUtil.CODE_PUSH_TEST_APP_NAME_PLACEHOLDER, PluginTestingFramework.TestAppName)); + } + + /** + * Installs the binary of the given project on this platform. + */ + installApp(projectDirectory: string): Q.Promise { + return TestUtil.getProcessOutput("xcrun simctl install booted " + this.getBinaryPath(projectDirectory)); + } + + /** + * Maps project directories to whether or not they have built an IOS project before. + * + * The first build of an IOS project does not always succeed, so we always try again when it fails. + * + * EXAMPLE: + * { + * "TEMP_DIR/test-run": true, + * "TEMP_DIR/updates": false + * } + */ + private static iosFirstBuild: any = {}; + + /** + * Builds the binary of the project on this platform. + */ + buildApp(projectDirectory: string): Q.Promise { + var iOSProject: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "ios"); + + return this.getEmulatorManager().getTargetEmulator() + .then((targetEmulator: string) => { + var hashRegEx = /([0-9A-Z-]*)/g; + var hashWithParen = hashRegEx.exec(targetEmulator)[0]; + var hash = hashWithParen.substr(1, hashWithParen.length - 2); + return TestUtil.getProcessOutput("xcodebuild -workspace " + path.join(iOSProject, PluginTestingFramework.TestAppName) + ".xcworkspace -scheme " + PluginTestingFramework.TestAppName + + " -configuration Release -destination \"platform=iOS Simulator,id=" + hash + "\" -derivedDataPath build", { cwd: iOSProject, maxBuffer: 1024 * 1000 * 10 }, false); + }) + .then( + () => { return null; }, + () => { + // The first time an iOS project is built, it fails because it does not finish building libReact.a before it builds the test app. + // Simply build again to fix the issue. + if (!RNIOS.iosFirstBuild[projectDirectory]) { + RNIOS.iosFirstBuild[projectDirectory] = true; + return this.buildApp(projectDirectory); + } + return null; + }); + } +} + +var supportedTargetPlatforms: Platform.IPlatform[] = [new RNAndroid(), new RNIOS()]; + +////////////////////////////////////////////////////////////////////////////////////////// // Create the ProjectManager to use for the tests. + class RNProjectManager extends ProjectManager { /** * Returns the name of the plugin being tested, ie Cordova or React-Native @@ -44,7 +277,7 @@ class RNProjectManager extends ProjectManager { // If it is a file, just copy directly if (fileStats && fileStats.isFile()) { - promises.push(ProjectManager.copyFile(fileInFrom, fileInTo, true)); + promises.push(TestUtil.copyFile(fileInFrom, fileInTo, true)); } else { // If it is a directory, create the directory if it doesn't exist on the target and then copy over @@ -71,9 +304,9 @@ class RNProjectManager extends ProjectManager { mkdirp.sync(projectDirectory); // React-Native adds a "com." to the front of the name you provide, so provide the namespace with the "com." removed - return ProjectManager.execChildProcess("react-native init " + appName + " --package " + appNamespace, { cwd: projectDirectory }, true) + return TestUtil.getProcessOutput("react-native init " + appName + " --package " + appNamespace, { cwd: projectDirectory }, true) .then(this.copyTemplate.bind(this, templatePath, projectDirectory)) - .then(ProjectManager.execChildProcess.bind(undefined, "npm install " + PluginTestingFramework.thisPluginPath, { cwd: path.join(projectDirectory, PluginTestingFramework.TestAppName) })); + .then(TestUtil.getProcessOutput.bind(undefined, "npm install " + PluginTestingFramework.thisPluginPath, { cwd: path.join(projectDirectory, PluginTestingFramework.TestAppName) })); } /** JSON mapping project directories to the current scenario @@ -111,17 +344,14 @@ class RNProjectManager extends ProjectManager { var scenarioJs = "scenarios/" + jsPath; - // var packageFile = eval("(" + fs.readFileSync("./package.json", "utf8") + ")"); - // var pluginVersion = packageFile.version; - console.log("Setting up scenario " + jsPath + " in " + projectDirectory); // Copy index html file and replace - return ProjectManager.copyFile(templateIndexPath, destinationIndexPath, true) - .then(ProjectManager.replaceString.bind(undefined, destinationIndexPath, ProjectManager.CODE_PUSH_TEST_APP_NAME_PLACEHOLDER, PluginTestingFramework.TestAppName)) - .then(ProjectManager.replaceString.bind(undefined, destinationIndexPath, ProjectManager.SERVER_URL_PLACEHOLDER, targetPlatform.getServerUrl())) - .then(ProjectManager.replaceString.bind(undefined, destinationIndexPath, ProjectManager.INDEX_JS_PLACEHOLDER, scenarioJs)) - .then(ProjectManager.replaceString.bind(undefined, destinationIndexPath, ProjectManager.CODE_PUSH_APP_VERSION_PLACEHOLDER, version)); + return TestUtil.copyFile(templateIndexPath, destinationIndexPath, true) + .then(TestUtil.replaceString.bind(undefined, destinationIndexPath, TestUtil.CODE_PUSH_TEST_APP_NAME_PLACEHOLDER, PluginTestingFramework.TestAppName)) + .then(TestUtil.replaceString.bind(undefined, destinationIndexPath, TestUtil.SERVER_URL_PLACEHOLDER, targetPlatform.getServerUrl())) + .then(TestUtil.replaceString.bind(undefined, destinationIndexPath, TestUtil.INDEX_JS_PLACEHOLDER, scenarioJs)) + .then(TestUtil.replaceString.bind(undefined, destinationIndexPath, TestUtil.CODE_PUSH_APP_VERSION_PLACEHOLDER, version)); } /** @@ -134,9 +364,7 @@ class RNProjectManager extends ProjectManager { */ var bundleFolder: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "CodePush/"); - var bundleName: string; - if (targetPlatform === Platform.IOS.getInstance()) bundleName = "main.jsbundle"; - if (targetPlatform === Platform.Android.getInstance()) bundleName = "index.android.bundle"; + var bundleName: string = (targetPlatform).getBundleName(); var bundlePath: string = path.join(bundleFolder, bundleName); var deferred = Q.defer(); fs.exists(bundleFolder, (exists) => { @@ -145,10 +373,9 @@ class RNProjectManager extends ProjectManager { deferred.resolve(undefined); }); return deferred.promise - .then(ProjectManager.execChildProcess.bind(undefined, "react-native bundle --platform " + targetPlatform.getName() + " --entry-file index." + targetPlatform.getName() + ".js --bundle-output " + bundlePath + " --assets-dest " + bundleFolder + " --dev false", + .then(TestUtil.getProcessOutput.bind(undefined, "react-native bundle --platform " + targetPlatform.getName() + " --entry-file index." + targetPlatform.getName() + ".js --bundle-output " + bundlePath + " --assets-dest " + bundleFolder + " --dev false", { cwd: path.join(projectDirectory, PluginTestingFramework.TestAppName) })) - // NOTE: Android does not support diffs, so always pass false if targetPlatform is Android. - .then(ProjectManager.archiveFolder.bind(undefined, bundleFolder, path.join(projectDirectory, PluginTestingFramework.TestAppName, "update.zip"), targetPlatform !== Platform.Android.getInstance() && isDiff)); + .then(TestUtil.archiveFolder.bind(undefined, bundleFolder, path.join(projectDirectory, PluginTestingFramework.TestAppName, "update.zip"), (targetPlatform).isDiffsSupported() && isDiff)); } /** JSON file containing the platforms the plugin is currently installed for. @@ -162,85 +389,13 @@ class RNProjectManager extends ProjectManager { */ private static platformsJSON: string = "platforms.json"; - /** - * Installs the CodePush plugin for Android and prepares the test app to run Android tests. - */ - public static installCodePushAndPrepareAndroid(innerProjectFolder: string): Q.Promise { - //// Set up gradle to build CodePush with the app - // Add CodePush to android/app/build.gradle - var buildGradle = path.join(innerProjectFolder, "android", "app", "build.gradle"); - ProjectManager.replaceString(buildGradle, - "apply from: \"../../node_modules/react-native/react.gradle\"", - "apply from: \"../../node_modules/react-native/react.gradle\"\napply from: \"" + path.join(innerProjectFolder, "node_modules", "react-native-code-push", "android", "codepush.gradle") + "\""); - ProjectManager.replaceString(buildGradle, - "compile \"com.facebook.react:react-native:+\"", - "compile \"com.facebook.react:react-native:0.25.+\""); - ProjectManager.replaceString(buildGradle, - "// From node_modules", - "\n compile project(':react-native-code-push') // From node_modules"); - // Add CodePush to android/settings.gradle - ProjectManager.replaceString(path.join(innerProjectFolder, "android", "settings.gradle"), - "include ':app'", - "include ':app', ':react-native-code-push'\nproject(':react-native-code-push').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-code-push/android/app')"); - - //// Set the app version to 1.0.0 instead of 1.0 - // Set the app version to 1.0.0 in android/app/build.gradle - ProjectManager.replaceString(buildGradle, "versionName \"1.0\"", "versionName \"1.0.0\""); - // Set the app version to 1.0.0 in AndroidManifest.xml - ProjectManager.replaceString(path.join(innerProjectFolder, "android", "app", "src", "main", "AndroidManifest.xml"), "android:versionName=\"1.0\"", "android:versionName=\"1.0.0\""); - - //// Replace the MainActivity.java with the correct server url and deployment key - var mainActivity = path.join(innerProjectFolder, "android", "app", "src", "main", "java", "com", "microsoft", "codepush", "test", "MainActivity.java"); - ProjectManager.replaceString(mainActivity, ProjectManager.CODE_PUSH_TEST_APP_NAME_PLACEHOLDER, PluginTestingFramework.TestAppName); - ProjectManager.replaceString(mainActivity, ProjectManager.SERVER_URL_PLACEHOLDER, Platform.Android.getInstance().getServerUrl()); - ProjectManager.replaceString(mainActivity, ProjectManager.ANDROID_KEY_PLACEHOLDER, Platform.Android.getInstance().getDefaultDeploymentKey()); - - return Q(undefined); - } - - /** - * Installs the CodePush plugin for Android and prepares the test app to run Android tests. - */ - public static installCodePushAndPrepareIOS(innerProjectFolder: string): Q.Promise { - var iOSProject: string = path.join(innerProjectFolder, "ios"); - var infoPlistPath: string = path.join(iOSProject, PluginTestingFramework.TestAppName, "Info.plist"); - var appDelegatePath: string = path.join(iOSProject, PluginTestingFramework.TestAppName, "AppDelegate.m"); - // Create and install the Podfile - return ProjectManager.execChildProcess("pod init", { cwd: iOSProject }) - .then(() => { return fs.appendFileSync(path.join(iOSProject, "Podfile"), - "target '" + PluginTestingFramework.TestAppName + "'\n pod 'React', :path => '../node_modules/react-native', :subspecs => [ 'Core', 'RCTImage', 'RCTNetwork', 'RCTText', 'RCTWebSocket', ]\n pod 'CodePush', :path => '../node_modules/react-native-code-push'\n"); }) - // Put the IOS deployment key in the Info.plist - .then(ProjectManager.replaceString.bind(undefined, infoPlistPath, - "\n", - "CodePushDeploymentKey\n\t" + Platform.IOS.getInstance().getDefaultDeploymentKey() + "\n\tCodePushServerURL\n\t" + Platform.IOS.getInstance().getServerUrl() + "\n\t\n")) - // Add the correct linker flags to the project.pbxproj - .then(ProjectManager.replaceString.bind(undefined, path.join(iOSProject, PluginTestingFramework.TestAppName + ".xcodeproj", "project.pbxproj"), - "\"-lc[+][+]\",", "\"-lc++\", \"$(inherited)\"")) - // Install the Pod - .then(ProjectManager.execChildProcess.bind(undefined, "pod install", { cwd: iOSProject })) - // Add the correct bundle identifier to the Info.plist - .then(ProjectManager.replaceString.bind(undefined, infoPlistPath, - "org[.]reactjs[.]native[.]example[.][$][(]PRODUCT_NAME:rfc1034identifier[)]", - PluginTestingFramework.TestNamespace)) - // Set the app version to 1.0.0 instead of 1.0 in the Info.plist - .then(ProjectManager.replaceString.bind(undefined, infoPlistPath, "1.0", "1.0.0")) - // Fix the linker flag list in project.pbxproj (pod install adds an extra comma) - .then(ProjectManager.replaceString.bind(undefined, path.join(iOSProject, PluginTestingFramework.TestAppName + ".xcodeproj", "project.pbxproj"), - "\"[$][(]inherited[)]\",\\s*[)];", "\"$(inherited)\"\n\t\t\t\t);")) - // Copy the AppDelegate.m to the project - .then(ProjectManager.copyFile.bind(undefined, - path.join(PluginTestingFramework.templatePath, "ios", PluginTestingFramework.TestAppName, "AppDelegate.m"), - appDelegatePath, true)) - .then(ProjectManager.replaceString.bind(undefined, appDelegatePath, ProjectManager.CODE_PUSH_TEST_APP_NAME_PLACEHOLDER, PluginTestingFramework.TestAppName)) - } - /** * Prepares a specific platform for tests. */ - public preparePlatform(projectFolder: string, targetPlatform: Platform.IPlatform): Q.Promise { + public preparePlatform(projectDirectory: string, targetPlatform: Platform.IPlatform): Q.Promise { var deferred= Q.defer(); - var platformsJSONPath = path.join(projectFolder, RNProjectManager.platformsJSON); + var platformsJSONPath = path.join(projectDirectory, RNProjectManager.platformsJSON); // We create a JSON file in the project folder to contain the installed platforms. // Check the file to see if the plugin for this platform has been installed and update the file appropriately. @@ -250,7 +405,7 @@ class RNProjectManager extends ProjectManager { } var platformJSON = eval("(" + fs.readFileSync(platformsJSONPath, "utf8") + ")"); - if (platformJSON[targetPlatform.getName()] === true) deferred.reject("Platform " + targetPlatform.getName() + " is already installed in " + projectFolder + "!"); + if (platformJSON[targetPlatform.getName()] === true) deferred.reject("Platform " + targetPlatform.getName() + " is already installed in " + projectDirectory + "!"); else { platformJSON[targetPlatform.getName()] = true; fs.writeFileSync(platformsJSONPath, JSON.stringify(platformJSON)); @@ -258,122 +413,49 @@ class RNProjectManager extends ProjectManager { } }); - var innerProjectFolder: string = path.join(projectFolder, PluginTestingFramework.TestAppName); - return deferred.promise .then(() => { - if (targetPlatform === Platform.Android.getInstance()) { - return RNProjectManager.installCodePushAndPrepareAndroid(innerProjectFolder); - } else if (targetPlatform === Platform.IOS.getInstance()) { - return RNProjectManager.installCodePushAndPrepareIOS(innerProjectFolder); - } - }, (error) => { /* The platform is already installed! */ console.log(error); return null; }); + return (targetPlatform).installPlatform(projectDirectory); + }, (error: any) => { /* The platform is already installed! */ console.log(error); return null; }); } /** * Cleans up a specific platform after tests. */ - public cleanupAfterPlatform(projectFolder: string, targetPlatform: Platform.IPlatform): Q.Promise { + public cleanupAfterPlatform(projectDirectory: string, targetPlatform: Platform.IPlatform): Q.Promise { // Can't uninstall from command line, so noop. return Q(undefined); } - - private static getApkPath(projectDirectory: string): string { - return path.join(projectDirectory, PluginTestingFramework.TestAppName, "android", "app", "build", "outputs", "apk", "app-release-unsigned.apk"); - } - - /** - * Builds the test app on Android. - */ - public static buildAndroid(projectDirectory: string): Q.Promise { - // In order to run on Android without the package manager, we must create a release APK and then sign it with the debug certificate. - var androidDirectory: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "android"); - var apkPath = RNProjectManager.getApkPath(projectDirectory); - return ProjectManager.execChildProcess("./gradlew assembleRelease --daemon", { cwd: androidDirectory }) - .then(ProjectManager.execChildProcess.bind(undefined, "jarsigner -verbose -keystore ~/.android/debug.keystore -storepass android -keypass android " + apkPath + " androiddebugkey", { cwd: androidDirectory }, false)); - } - - /** - * Maps project directories to whether or not they have built an IOS project before. - * - * Currently, React-Native resets your bundle identifier on the first build of the app. - * Obviously we don't want this, so on the first build we need to fix the package name and build again. - * - * EXAMPLE: - * { - * "TEMP_DIR/test-run": true, - * "TEMP_DIR/updates": false - * } - */ - private static iosFirstBuild: any = {}; - - /** - * Builds the test app on IOS. - */ - public static buildIOS(projectDirectory: string): Q.Promise { - // NOTE: fix this for any device - var iOSProject: string = path.join(projectDirectory, PluginTestingFramework.TestAppName, "ios"); - - // Don't log the build output because iOS's build output is too verbose and overflows the buffer! - return ProjectManager.execChildProcess("xcodebuild -workspace " + path.join(iOSProject, PluginTestingFramework.TestAppName) + ".xcworkspace -scheme " + PluginTestingFramework.TestAppName + " -configuration Release -destination \"platform=iOS Simulator,id=" + - "A63E7FA6-05E4-4726-A8FA-A61B95652D65" + "\" -derivedDataPath build", { cwd: iOSProject, maxBuffer: 1024 * 1000 * 10 }, false) - .then( - () => { return null; }, - () => { - // The first time an iOS project is built, it fails because it does not finish building libReact.a before it builds the test app. - // Simply build again to fix the issue. - if (!RNProjectManager.iosFirstBuild[projectDirectory]) { - RNProjectManager.iosFirstBuild[projectDirectory] = true; - return RNProjectManager.buildIOS(projectDirectory); - } - return null; - }); - } - - /** - * Builds the test app on the specified platform. - */ - public static buildTestApp(projectDirectory: string, targetPlatform: Platform.IPlatform): Q.Promise { - if (targetPlatform === Platform.Android.getInstance()) { - return RNProjectManager.buildAndroid(projectDirectory); - } else if (targetPlatform === Platform.IOS.getInstance()) { - return RNProjectManager.buildIOS(projectDirectory); - } - return Q(undefined); - } /** * Runs the test app on the given target / platform. */ - public runPlatform(projectFolder: string, targetPlatform: Platform.IPlatform): Q.Promise { - console.log("Running project in " + projectFolder + " on " + targetPlatform.getName()); + public runApplication(projectDirectory: string, targetPlatform: Platform.IPlatform): Q.Promise { + console.log("Running project in " + projectDirectory + " on " + targetPlatform.getName()); return Q(undefined) .then(() => { // Build if this scenario has not yet been built. - if (!RNProjectManager.currentScenarioHasBuilt[projectFolder]) { - RNProjectManager.currentScenarioHasBuilt[projectFolder] = true; - return RNProjectManager.buildTestApp(projectFolder, targetPlatform); + if (!RNProjectManager.currentScenarioHasBuilt[projectDirectory]) { + RNProjectManager.currentScenarioHasBuilt[projectDirectory] = true; + return (targetPlatform).buildApp(projectDirectory); } }) .then(() => { - // Uninstall so that none of the app's data carries over between tests. + // Uninstall the app so that the app's data doesn't carry over between tests. return targetPlatform.getEmulatorManager().uninstallApplication(PluginTestingFramework.TestNamespace); }) .then(() => { - if (targetPlatform === Platform.Android.getInstance()) { - var androidDirectory: string = path.join(projectFolder, PluginTestingFramework.TestAppName, "android"); - return ProjectManager.execChildProcess("adb install -r " + RNProjectManager.getApkPath(projectFolder), { cwd: androidDirectory }) - .then(targetPlatform.getEmulatorManager().launchInstalledApplication.bind(undefined, PluginTestingFramework.TestNamespace)); - } else if (targetPlatform === Platform.IOS.getInstance()) { - var iOSProject: string = path.join(projectFolder, PluginTestingFramework.TestAppName, "ios"); - return ProjectManager.execChildProcess("xcrun simctl install booted " + path.join(iOSProject, "build", "Build", "Products", "Release-iphonesimulator", PluginTestingFramework.TestAppName + ".app")) - .then(targetPlatform.getEmulatorManager().launchInstalledApplication.bind(undefined, PluginTestingFramework.TestNamespace)); - } + // Install and launch the app. + return (targetPlatform).installApp(projectDirectory) + .then(targetPlatform.getEmulatorManager().launchInstalledApplication.bind(undefined, PluginTestingFramework.TestNamespace)); }); } }; +////////////////////////////////////////////////////////////////////////////////////////// +// Create the tests. + // Scenarios used in the tests. const ScenarioCheckForUpdatePath = "scenarioCheckForUpdate.js"; const ScenarioCheckForUpdateCustomKey = "scenarioCheckForUpdateCustomKey.js"; @@ -420,14 +502,14 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ } }; - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.checkForUpdate.sendsBinaryHash", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - if (targetPlatform === Platform.Android.getInstance()) { - console.log("Android does not send a binary hash!"); + if (!(targetPlatform).isDiffsSupported()) { + console.log(targetPlatform.getName() + " does not send a binary hash!"); done(); return; } @@ -455,7 +537,7 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ } }; - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.checkForUpdate.noUpdate.updateAppVersion", @@ -475,12 +557,12 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ } }; - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.checkForUpdate.update", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - var updateResponse = PluginTestingFramework.createMockResponse(); + var updateResponse = PluginTestingFramework.createUpdateResponse(); PluginTestingFramework.updateResponse = { updateInfo: updateResponse }; PluginTestingFramework.testMessageCallback = (requestBody: any) => { @@ -509,7 +591,7 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ } }; - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); }, true), new PluginTestingFramework.TestBuilderIt("window.codePush.checkForUpdate.error", @@ -525,7 +607,7 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ } }; - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); }, false) ], ScenarioCheckForUpdatePath), @@ -533,7 +615,7 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [new PluginTestingFramework.TestBuilderIt("window.codePush.checkForUpdate.customKey.update", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - var updateResponse = PluginTestingFramework.createMockResponse(); + var updateResponse = PluginTestingFramework.createUpdateResponse(); PluginTestingFramework.updateResponse = { updateInfo: updateResponse }; PluginTestingFramework.updateCheckCallback = (request: any) => { @@ -546,7 +628,7 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ } }; - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); }, false)], ScenarioCheckForUpdateCustomKey), @@ -555,36 +637,32 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("remotePackage.download.success", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* pass the path to any file for download (here, index.js) to make sure the download completed callback is invoked */ PluginTestingFramework.updatePackagePath = path.join(PluginTestingFramework.templatePath, "index.js"); - var deferred = Q.defer(); - deferred.promise.then(() => { done(); }, (e) => { done(e); }); - - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + + PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, - ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED], deferred); - - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED]) + .then(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("remotePackage.download.error", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* pass an invalid path */ PluginTestingFramework.updatePackagePath = path.join(PluginTestingFramework.templatePath, "invalid_path.zip"); - var deferred = Q.defer(); - deferred.promise.then(() => { done(); }, (e) => { done(e); }); - - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + + PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, - ServerUtil.TestMessage.DOWNLOAD_ERROR], deferred); - - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + ServerUtil.TestMessage.DOWNLOAD_ERROR]) + .then(() => { done(); }, (e) => { done(e); }); }, false) ], ScenarioDownloadUpdate), @@ -594,7 +672,7 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ // // CHANGE THIS TEST CASE, accepts both a jsbundle and a zip // new PluginTestingFramework.TestBuilderIt("localPackage.install.unzip.error", // (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - // PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + // PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; // /* pass an invalid zip file, here, index.js */ // PluginTestingFramework.updatePackagePath = path.join(PluginTestingFramework.templatePath, "index.js"); @@ -607,65 +685,57 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ // ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, // ServerUtil.TestMessage.INSTALL_ERROR], deferred); - // projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); + // projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); // }, false), new PluginTestingFramework.TestBuilderIt("localPackage.install.handlesDiff.againstBinary", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - if (targetPlatform === Platform.Android.getInstance()) { - console.log("Android does not support diffs!"); + if (!(targetPlatform).isDiffsSupported()) { + console.log(targetPlatform.getName() + " does not support diffs!"); done(); return; } - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReady, "Diff Update 1") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* run the app again to ensure it was not reverted */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("localPackage.install.immediately", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReady, "Update 1") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* run the app again to ensure it was not reverted */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, false) @@ -676,63 +746,53 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("localPackage.install.revert.dorevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (bad update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* restart the app to ensure it was reverted and send it another update */ - var deferred = Q.defer(); - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* restart the app again to ensure it was reverted again and send the same update and expect it to reject it */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("localPackage.install.revert.norevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReady, "Update 1 (good update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* run the app again to ensure it was not reverted */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, false) @@ -743,65 +803,53 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("localPackage.installOnNextResume.dorevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.UPDATE_INSTALLED], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.UPDATE_INSTALLED]); }) .then(() => { /* resume the application */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.resumeApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().resumeApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* restart to revert it */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY]); }) .done(() => { done(); }, (e) => { done(e); }); }, true), new PluginTestingFramework.TestBuilderIt("localPackage.installOnNextResume.norevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReady, "Update 1 (good update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.UPDATE_INSTALLED], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.UPDATE_INSTALLED]); }) .then(() => { /* resume the application */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.resumeApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().resumeApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* restart to make sure it did not revert */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, true) @@ -812,122 +860,104 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("localPackage.installOnNextRestart.dorevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.UPDATE_INSTALLED], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.UPDATE_INSTALLED]); }) .then(() => { /* restart the application */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); console.log("Update hash: " + PluginTestingFramework.updateResponse.updateInfo.packageHash); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* restart the application */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY], deferred); console.log("Update hash: " + PluginTestingFramework.updateResponse.updateInfo.packageHash); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("localPackage.installOnNextRestart.norevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReady, "Update 1 (good update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.UPDATE_INSTALLED], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.UPDATE_INSTALLED]); }) .then(() => { /* "resume" the application - run it again */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* run again to make sure it did not revert */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, true), new PluginTestingFramework.TestBuilderIt("localPackage.installOnNextRestart.revertToPrevious", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReadyConditional, "Update 1 (good update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.UPDATE_INSTALLED], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.UPDATE_INSTALLED]); }) .then(() => { /* run good update, set up another (bad) update */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; + PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 2 (bad update)") + .then(() => { return targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); }); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, ServerUtil.TestMessage.CHECK_UPDATE_AVAILABLE, ServerUtil.TestMessage.DOWNLOAD_SUCCEEDED, - ServerUtil.TestMessage.UPDATE_INSTALLED], deferred); - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; - PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 2 (bad update)") - .then(() => { return projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); }); - return deferred.promise; + ServerUtil.TestMessage.UPDATE_INSTALLED]); }) .then(() => { /* run the bad update without calling notifyApplicationReady */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* run the good update and don't call notifyApplicationReady - it should not revert */ - var deferred = Q.defer(); PluginTestingFramework.testMessageResponse = ServerUtil.TestMessageResponse.SKIP_NOTIFY_APPLICATION_READY; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, ServerUtil.TestMessage.SKIPPED_NOTIFY_APPLICATION_READY], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, + ServerUtil.TestMessage.SKIPPED_NOTIFY_APPLICATION_READY]); }) .then(() => { /* run the application again */ - var deferred = Q.defer(); PluginTestingFramework.testMessageResponse = undefined; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, + ServerUtil.TestMessage.UPDATE_FAILED_PREVIOUSLY]); }) .done(() => { done(); }, (e) => { done(e); }); }, false) @@ -938,31 +968,24 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("codePush.restartApplication.checkPackages", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateNotifyApplicationReady, "Update 1") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.PENDING_PACKAGE, [null]), new ServerUtil.AppMessage(ServerUtil.TestMessage.CURRENT_PACKAGE, [null]), new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), new ServerUtil.AppMessage(ServerUtil.TestMessage.PENDING_PACKAGE, [PluginTestingFramework.updateResponse.updateInfo.packageHash]), new ServerUtil.AppMessage(ServerUtil.TestMessage.CURRENT_PACKAGE, [null]), - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE - ], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { /* restart the application */ - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE - ], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, true) @@ -984,12 +1007,9 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ Q({}) .then(p => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), @@ -1000,88 +1020,74 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ Q({}) .then(p => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.sync.downloaderror", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - var invalidUrlResponse = PluginTestingFramework.createMockResponse(); + var invalidUrlResponse = PluginTestingFramework.createUpdateResponse(); invalidUrlResponse.downloadURL = path.join(PluginTestingFramework.templatePath, "invalid_path.zip"); PluginTestingFramework.updateResponse = { updateInfo: invalidUrlResponse }; Q({}) .then(p => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.sync.dorevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (bad update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform).done(); - return deferred.promise; + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.sync.update", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateSync, "Update 1 (good update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), // the update is immediate so the update will install ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .then(() => { // restart the app and make sure it didn't roll out! - var deferred = Q.defer(); var noUpdateResponse = PluginTestingFramework.createDefaultResponse(); noUpdateResponse.isAvailable = false; noUpdateResponse.appVersion = "0.0.1"; PluginTestingFramework.updateResponse = { updateInfo: noUpdateResponse }; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false) @@ -1100,13 +1106,10 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ Q({}) .then(p => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), @@ -1117,99 +1120,81 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ Q({}) .then(p => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.sync.2x.downloaderror", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - var invalidUrlResponse = PluginTestingFramework.createMockResponse(); + var invalidUrlResponse = PluginTestingFramework.createUpdateResponse(); invalidUrlResponse.downloadURL = path.join(PluginTestingFramework.templatePath, "invalid_path.zip"); PluginTestingFramework.updateResponse = { updateInfo: invalidUrlResponse }; Q({}) .then(p => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_ERROR])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.sync.2x.dorevert", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (bad update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .then(() => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], - deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("window.codePush.sync.2x.update", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; /* create an update */ PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateSync2x, "Update 1 (good update)") .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), // the update is immediate so the update will install ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], - deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .then(() => { // restart the app and make sure it didn't roll out! - var deferred = Q.defer(); var noUpdateResponse = PluginTestingFramework.createDefaultResponse(); noUpdateResponse.isAvailable = false; noUpdateResponse.appVersion = "0.0.1"; PluginTestingFramework.updateResponse = { updateInfo: noUpdateResponse }; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_IN_PROGRESS]), - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], - deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, true) @@ -1221,93 +1206,81 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("defaults to no minimum", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.setupScenario(projectManager, targetPlatform, ScenarioSyncResume).then(() => { return PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateSync, "Update 1 (good update)"); }) .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])]); }) .then(() => { - var deferred = Q.defer(); var noUpdateResponse = PluginTestingFramework.createDefaultResponse(); noUpdateResponse.isAvailable = false; noUpdateResponse.appVersion = "0.0.1"; PluginTestingFramework.updateResponse = { updateInfo: noUpdateResponse }; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + targetPlatform.getEmulatorManager().resumeApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], deferred); - projectManager.resumeApplication(PluginTestingFramework.TestNamespace, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("min background duration 5s", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.setupScenario(projectManager, targetPlatform, ScenarioSyncResumeDelay).then(() => { return PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateSync, "Update 1 (good update)"); }) .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])]); }) .then(() => { var noUpdateResponse = PluginTestingFramework.createDefaultResponse(); noUpdateResponse.isAvailable = false; noUpdateResponse.appVersion = "0.0.1"; PluginTestingFramework.updateResponse = { updateInfo: noUpdateResponse }; - return projectManager.resumeApplication(PluginTestingFramework.TestNamespace, targetPlatform, 3 * 1000); + return targetPlatform.getEmulatorManager().resumeApplication(PluginTestingFramework.TestNamespace, 3 * 1000); }) .then(() => { - var deferred = Q.defer(); - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + targetPlatform.getEmulatorManager().resumeApplication(PluginTestingFramework.TestNamespace, 6 * 1000); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], deferred); - projectManager.resumeApplication(PluginTestingFramework.TestNamespace, targetPlatform, 6 * 1000).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("has no effect on restart", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.setupScenario(projectManager, targetPlatform, ScenarioSyncRestartDelay).then(() => { return PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateSync, "Update 1 (good update)"); }) .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])]); }) .then(() => { - var deferred = Q.defer(); var noUpdateResponse = PluginTestingFramework.createDefaultResponse(); noUpdateResponse.isAvailable = false; noUpdateResponse.appVersion = "0.0.1"; PluginTestingFramework.updateResponse = { updateInfo: noUpdateResponse }; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + targetPlatform.getEmulatorManager().restartApplication(PluginTestingFramework.TestNamespace); + return PluginTestingFramework.expectTestMessages([ ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE, - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])], deferred); - projectManager.restartApplication(PluginTestingFramework.TestNamespace, targetPlatform).done(); - return deferred.promise; + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UP_TO_DATE])]); }) .done(() => { done(); }, (e) => { done(e); }); }, false) @@ -1318,72 +1291,66 @@ var testBuilderDescribes: PluginTestingFramework.TestBuilderDescribe[] = [ [ new PluginTestingFramework.TestBuilderIt("defaults to IMMEDIATE", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform, true) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(true, targetPlatform) }; PluginTestingFramework.setupScenario(projectManager, targetPlatform, ScenarioSyncMandatoryDefault).then(() => { return PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (good update)"); }) .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("works correctly when update is mandatory and mandatory install mode is specified", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform, true) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(true, targetPlatform) }; PluginTestingFramework.setupScenario(projectManager, targetPlatform, ScenarioSyncMandatoryResume).then(() => { return PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (good update)"); }) .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ + new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED])]); }) .then(() => { - var deferred = Q.defer(); var noUpdateResponse = PluginTestingFramework.createDefaultResponse(); noUpdateResponse.isAvailable = false; noUpdateResponse.appVersion = "0.0.1"; PluginTestingFramework.updateResponse = { updateInfo: noUpdateResponse }; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.resumeApplication(PluginTestingFramework.TestNamespace, targetPlatform, 5 * 1000).done(); - return deferred.promise; + targetPlatform.getEmulatorManager().resumeApplication(PluginTestingFramework.TestNamespace, 5 * 1000); + return PluginTestingFramework.expectTestMessages([ + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, false), new PluginTestingFramework.TestBuilderIt("has no effect on updates that are not mandatory", (projectManager: ProjectManager, targetPlatform: Platform.IPlatform, done: MochaDone) => { - PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.getMockResponse(targetPlatform) }; + PluginTestingFramework.updateResponse = { updateInfo: PluginTestingFramework.createUpdateResponse(false, targetPlatform) }; PluginTestingFramework.setupScenario(projectManager, targetPlatform, ScenarioSyncMandatoryRestart).then(() => { return PluginTestingFramework.createUpdate(projectManager, targetPlatform, UpdateDeviceReady, "Update 1 (good update)"); }) .then((updatePath: string) => { - var deferred = Q.defer(); PluginTestingFramework.updatePackagePath = updatePath; - PluginTestingFramework.testMessageCallback = PluginTestingFramework.verifyMessages([ + projectManager.runApplication(PluginTestingFramework.testRunDirectory, targetPlatform); + return PluginTestingFramework.expectTestMessages([ new ServerUtil.AppMessage(ServerUtil.TestMessage.SYNC_STATUS, [ServerUtil.TestMessage.SYNC_UPDATE_INSTALLED]), - ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE], deferred); - projectManager.runPlatform(PluginTestingFramework.testRunDirectory, targetPlatform).done(); - return deferred.promise; + ServerUtil.TestMessage.DEVICE_READY_AFTER_UPDATE]); }) .done(() => { done(); }, (e) => { done(e); }); }, false) ]) ]; -// Create tests. -PluginTestingFramework.initializeTests(new RNProjectManager(), testBuilderDescribes); \ No newline at end of file +////////////////////////////////////////////////////////////////////////////////////////// +// Initialize the tests. + +PluginTestingFramework.initializeTests(new RNProjectManager(), testBuilderDescribes, supportedTargetPlatforms); \ No newline at end of file diff --git a/typings/code-push-plugin-testing-framework.d.ts b/typings/code-push-plugin-testing-framework.d.ts index f769740..5f07891 100644 --- a/typings/code-push-plugin-testing-framework.d.ts +++ b/typings/code-push-plugin-testing-framework.d.ts @@ -8,14 +8,15 @@ declare module 'code-push-plugin-testing-framework/script/platform' { * Gets the platform name. (e.g. "android" for the Android platform). */ getName(): string; + /** + * The command line flag used to determine whether or not this platform should run. + * Runs when the flag is present, doesn't run otherwise. + */ + getCommandLineFlagName(): string; /** * Gets the server url used for testing. */ getServerUrl(): string; - /** - * Gets the root of the platform www folder used for creating update packages. - */ - getPlatformWwwPath(projectDirectory: string): string; /** * Gets an IEmulatorManager that is used to control the emulator during the tests. */ @@ -29,6 +30,10 @@ declare module 'code-push-plugin-testing-framework/script/platform' { * Manages the interaction with the emulator. */ export interface IEmulatorManager { + /** + * Returns the target emulator, which is specified through the command line. + */ + getTargetEmulator(): Q.Promise; /** * Boots the target emulator. */ @@ -48,7 +53,7 @@ declare module 'code-push-plugin-testing-framework/script/platform' { /** * Navigates away from the current app, waits for a delay (defaults to 1 second), then navigates to the specified app. */ - resumeApplication(appId: string, delayBeforeResumingMs: number): Q.Promise; + resumeApplication(appId: string, delayBeforeResumingMs?: number): Q.Promise; /** * Prepares the emulator for a test. */ @@ -62,69 +67,72 @@ declare module 'code-push-plugin-testing-framework/script/platform' { * Android implementations of IPlatform. */ export class Android implements IPlatform { - private static instance; private emulatorManager; private serverUrl; constructor(emulatorManager: IEmulatorManager); - static getInstance(): Android; + /** + * Gets the platform name. (e.g. "android" for the Android platform). + */ getName(): string; + /** + * The command line flag used to determine whether or not this platform should run. + * Runs when the flag is present, doesn't run otherwise. + */ + getCommandLineFlagName(): string; + private static ANDROID_SERVER_URL_OPTION_NAME; + private static DEFAULT_ANDROID_SERVER_URL; /** * Gets the server url used for testing. */ getServerUrl(): string; - getPlatformWwwPath(projectDirectory: string): string; + /** + * Gets an IEmulatorManager that is used to control the emulator during the tests. + */ getEmulatorManager(): IEmulatorManager; + /** + * Gets the default deployment key. + */ getDefaultDeploymentKey(): string; } /** * IOS implementation of IPlatform. */ export class IOS implements IPlatform { - private static instance; private emulatorManager; private serverUrl; constructor(emulatorManager: IEmulatorManager); - static getInstance(): IOS; + /** + * Gets the platform name. (e.g. "android" for the Android platform). + */ getName(): string; + /** + * The command line flag used to determine whether or not this platform should run. + * Runs when the flag is present, doesn't run otherwise. + */ + getCommandLineFlagName(): string; + private static IOS_SERVER_URL_OPTION_NAME; + private static DEFAULT_IOS_SERVER_URL; /** * Gets the server url used for testing. */ getServerUrl(): string; - getPlatformWwwPath(projectDirectory: string): string; + /** + * Gets an IEmulatorManager that is used to control the emulator during the tests. + */ getEmulatorManager(): IEmulatorManager; + /** + * Gets the default deployment key. + */ getDefaultDeploymentKey(): string; } - export class IOSEmulatorManager implements IEmulatorManager { - /** - * Boots the target emulator. - */ - bootEmulator(restartEmulators: boolean): Q.Promise; - /** - * Launches an already installed application by app id. - */ - launchInstalledApplication(appId: string): Q.Promise; - /** - * Ends a running application given its app id. - */ - endRunningApplication(appId: string): Q.Promise; - /** - * Restarts an already installed application by app id. - */ - restartApplication(appId: string): Q.Promise; - /** - * Navigates away from the current app, waits for a delay (defaults to 1 second), then navigates to the specified app. - */ - resumeApplication(appId: string, delayBeforeResumingMs?: number): Q.Promise; - /** - * Prepares the emulator for a test. - */ - prepareEmulatorForTest(appId: string): Q.Promise; - /** - * Uninstalls the app from the emulator. - */ - uninstallApplication(appId: string): Q.Promise; - } export class AndroidEmulatorManager implements IEmulatorManager { + private static ANDROID_EMULATOR_OPTION_NAME; + private static DEFAULT_ANDROID_EMULATOR; + private targetEmulator; + /** + * Returns the target emulator, which is specified through the command line. + */ + getTargetEmulator(): Q.Promise; /** * Boots the target emulator. */ @@ -154,19 +162,41 @@ declare module 'code-push-plugin-testing-framework/script/platform' { */ uninstallApplication(appId: string): Q.Promise; } - /** - * Supported platforms resolver. - */ - export class PlatformResolver { - private static supportedPlatforms; + export class IOSEmulatorManager implements IEmulatorManager { + private static IOS_EMULATOR_OPTION_NAME; + private targetEmulator; /** - * Given the cordova name of a platform, this method returns the IPlatform associated with it. + * Returns the target emulator, which is specified through the command line. */ - static resolvePlatforms(cordovaPlatformNames: string[]): IPlatform[]; + getTargetEmulator(): Q.Promise; /** - * Given the cordova name of a platform, this method returns the IPlatform associated with it. + * Boots the target emulator. */ - static resolvePlatform(cordovaPlatformName: string): IPlatform; + bootEmulator(restartEmulators: boolean): Q.Promise; + /** + * Launches an already installed application by app id. + */ + launchInstalledApplication(appId: string): Q.Promise; + /** + * Ends a running application given its app id. + */ + endRunningApplication(appId: string): Q.Promise; + /** + * Restarts an already installed application by app id. + */ + restartApplication(appId: string): Q.Promise; + /** + * Navigates away from the current app, waits for a delay (defaults to 1 second), then navigates to the specified app. + */ + resumeApplication(appId: string, delayBeforeResumingMs?: number): Q.Promise; + /** + * Prepares the emulator for a test. + */ + prepareEmulatorForTest(appId: string): Q.Promise; + /** + * Uninstalls the app from the emulator. + */ + uninstallApplication(appId: string): Q.Promise; } } @@ -177,17 +207,10 @@ declare module 'code-push-plugin-testing-framework/script/projectManager' { * In charge of project related operations. */ export class ProjectManager { - static ANDROID_KEY_PLACEHOLDER: string; - static IOS_KEY_PLACEHOLDER: string; - static SERVER_URL_PLACEHOLDER: string; - static INDEX_JS_PLACEHOLDER: string; - static CODE_PUSH_APP_VERSION_PLACEHOLDER: string; - static CODE_PUSH_APP_ID_PLACEHOLDER: string; - static PLUGIN_VERSION_PLACEHOLDER: string; static DEFAULT_APP_VERSION: string; private static NOT_IMPLEMENTED_ERROR_MSG; /** - * Returns the name of the plugin being tested, ie Cordova or React-Native. + * Returns the name of the plugin being tested, for example Cordova or React-Native. * * Overwrite this in your implementation! */ @@ -216,168 +239,19 @@ declare module 'code-push-plugin-testing-framework/script/projectManager' { * * Overwrite this in your implementation! */ - preparePlatform(projectFolder: string, targetPlatform: platform.IPlatform): Q.Promise; + preparePlatform(projectDirectory: string, targetPlatform: platform.IPlatform): Q.Promise; /** * Cleans up a specific platform after tests. * * Overwrite this in your implementation! */ - cleanupAfterPlatform(projectFolder: string, targetPlatform: platform.IPlatform): Q.Promise; + cleanupAfterPlatform(projectDirectory: string, targetPlatform: platform.IPlatform): Q.Promise; /** * Runs the test app on the given target / platform. * * Overwrite this in your implementation! */ - runPlatform(projectFolder: string, targetPlatform: platform.IPlatform): Q.Promise; - /** - * Launch the test app on the given target / platform. - */ - launchApplication(appNamespace: string, targetPlatform: platform.IPlatform): Q.Promise; - /** - * Kill the test app on the given target / platform. - */ - endRunningApplication(appNamespace: string, targetPlatform: platform.IPlatform): Q.Promise; - /** - * Prepares the emulator for a test. - */ - prepareEmulatorForTest(appNamespace: string, targetPlatform: platform.IPlatform): Q.Promise; - /** - * Uninstalls the app from the emulator. - */ - uninstallApplication(appNamespace: string, targetPlatform: platform.IPlatform): Q.Promise; - /** - * Stops and restarts an application specified by its namespace identifier. - */ - restartApplication(appNamespace: string, targetPlatform: platform.IPlatform): Q.Promise; - /** - * Navigates away from the application and then navigates back to it. - */ - resumeApplication(appNamespace: string, targetPlatform: platform.IPlatform, delayBeforeResumingMs?: number): Q.Promise; - /** - * Executes a child process and logs its output to the console and returns its output in the promise as a string - */ - static execChildProcess(command: string, options?: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - }, logOutput?: boolean): Q.Promise; - /** - * Replaces a regex in a file with a given string. - */ - static replaceString(filePath: string, regex: string, replacement: string): void; - /** - * Copies a file from a given location to another. - */ - static copyFile(source: string, destination: string, overwrite: boolean): Q.Promise; - /** - * Archives the contents of targetFolder and puts it in an archive at archivePath. - */ - static archiveFolder(targetFolder: string, archivePath: string, isDiff: boolean): Q.Promise; - } - -} -declare module 'code-push-plugin-testing-framework/script/testUtil' { - import Q = require("q"); - export class TestUtil { - static ANDROID_PLATFORM_OPTION_NAME: string; - static ANDROID_SERVER_URL: string; - static defaultAndroidServerUrl: string; - static ANDROID_EMULATOR: string; - static defaultAndroidEmulator: string; - static IOS_PLATFORM_OPTION_NAME: string; - static IOS_SERVER_URL: string; - static defaultIOSServerUrl: string; - static IOS_EMULATOR: string; - static SHOULD_USE_WKWEBVIEW: string; - static templatePath: string; - static thisPluginPath: string; - static TEST_RUN_DIRECTORY: string; - private static defaultTestRunDirectory; - static TEST_UPDATES_DIRECTORY: string; - private static defaultUpdatesDirectory; - static CORE_TESTS_ONLY: string; - static PULL_FROM_NPM: string; - static SETUP: string; - static RESTART_EMULATORS: string; - /** - * Reads the directory in which the test project is. - */ - static readTestRunDirectory(): string; - /** - * Reads the directory in which the test project for updates is. - */ - static readTestUpdatesDirectory(): string; - /** - * Reads the path of the plugin (whether or not we should use the local copy or pull from npm) - */ - static readPluginPath(): string; - /** - * Reads the Android server url to use - */ - static readAndroidServerUrl(): string; - /** - * Reads the iOS server url to use - */ - static readIOSServerUrl(): string; - /** - * Reads the Android emulator to use - */ - static readAndroidEmulator(): string; - /** - * Reads the iOS emulator to use - */ - static readIOSEmulator(): Q.Promise; - /** - * Reads whether or not emulators should be restarted. - */ - static readRestartEmulators(): boolean; - /** - * Reads whether or not only core tests should be run. - */ - static readCoreTestsOnly(): boolean; - /** - * Reads whether or not to setup the test project directories. - */ - static readShouldSetup(): boolean; - /** - * Reads the test target platforms. - */ - static readTargetPlatforms(): string[]; - /** - * Reads if we should use the WkWebView or the UIWebView or run tests for both. - * 0 for UIWebView, 1 for WkWebView, 2 for both - */ - static readShouldUseWkWebView(): number; - /** - * Reads command line options passed to mocha. - */ - private static readMochaCommandLineOption(optionName); - /** - * Reads command line options passed to mocha. - */ - private static readMochaCommandLineFlag(optionName); - /** - * Executes a child process returns its output as a string. - */ - static getProcessOutput(command: string, options?: { - cwd?: string; - stdio?: any; - customFds?: any; - env?: any; - encoding?: string; - timeout?: number; - maxBuffer?: number; - killSignal?: string; - }, logOutput?: boolean): Q.Promise; - /** - * Returns the name of the plugin that is being tested. - */ - static getPluginName(): string; + runApplication(projectDirectory: string, targetPlatform: platform.IPlatform): Q.Promise; } } @@ -461,11 +335,17 @@ declare module 'code-push-plugin-testing-framework/script/test' { import platform = require('code-push-plugin-testing-framework/script/platform'); import Q = require("q"); import tm = require('code-push-plugin-testing-framework/script/projectManager'); - import tu = require('code-push-plugin-testing-framework/script/testUtil'); import su = require('code-push-plugin-testing-framework/script/serverUtil'); export const TestAppName: string; export const TestNamespace: string; export const AcquisitionSDKPluginName: string; + export const templatePath: string; + export const thisPluginPath: string; + export const testRunDirectory: string; + export const updatesDirectory: string; + export const onlyRunCoreTests: boolean; + export const shouldSetup: boolean; + export const restartEmulators: boolean; /** Response the server gives the next update check request */ export var updateResponse: any; /** Response the server gives the next test message request */ @@ -476,17 +356,10 @@ declare module 'code-push-plugin-testing-framework/script/test' { export var updateCheckCallback: (requestBody: any) => void; /** Location of the update package given in the update check response */ export var updatePackagePath: string; - export var testUtil: typeof tu.TestUtil; - export var templatePath: string; - export var thisPluginPath: string; - export var testRunDirectory: string; - export var updatesDirectory: string; - export var onlyRunCoreTests: boolean; - export var targetPlatforms: platform.IPlatform[]; - export var shouldUseWkWebView: number; - export var shouldSetup: boolean; - export var restartEmulators: boolean; - export interface TestBuilder { + export class TestBuilder { + only: boolean; + skip: boolean; + constructor(options: any); /** * Called to create the test suite by the initializeTests function * @@ -497,7 +370,7 @@ declare module 'code-push-plugin-testing-framework/script/test' { create(coreTestsOnly: boolean, projectManager: tm.ProjectManager, targetPlatform: platform.IPlatform): void; } /** Use this class to create a mocha.describe that contains additional tests */ - export class TestBuilderDescribe implements TestBuilder { + export class TestBuilderDescribe extends TestBuilder { /** The name passed to the describe */ private describeName; /** The path to the scenario that will be loaded by the test app for the nested TestBuilder objects */ @@ -506,15 +379,15 @@ declare module 'code-push-plugin-testing-framework/script/test' { private testBuilders; /** Whether or not this.testBuilders directly contains any TestBuildIt objects */ private hasIts; - /** The function that create calls (used for describe.only) */ - private functionToUse; + /** Whether or not this.testBuilders directly contains any TestBuilder objects that are only */ + hasOnly: boolean; /** * describeName - used as the description in the call to describe * scenarioPath - if specified, will be set up before the tests run * testBuilders - the testBuilders to create within this describe call * only - if true, use describe.only */ - constructor(describeName: string, testBuilders: TestBuilder[], scenarioPath?: string, only?: boolean); + constructor(describeName: string, testBuilders: TestBuilder[], scenarioPath?: string, options?: any); /** * Called to create the test suite by the initializeTests function * @@ -525,22 +398,20 @@ declare module 'code-push-plugin-testing-framework/script/test' { create(coreTestsOnly: boolean, projectManager: tm.ProjectManager, targetPlatform: platform.IPlatform): void; } /** Use this class to create a test through mocha.it */ - export class TestBuilderIt implements TestBuilder { + export class TestBuilderIt extends TestBuilder { /** The name of the test */ private testName; /** The test to be run */ private test; /** Whether or not the test should be run when "--core" is supplied */ private isCoreTest; - /** The function that create calls (used for it.only) */ - private functionToUse; /** * testName - used as the expectation in the call to it * test - the test to provide to it * isCoreTest - whether or not the test should run when "--core" is supplied * only - if true, use it.only */ - constructor(testName: string, test: (projectManager: tm.ProjectManager, targetPlatform: platform.IPlatform, done: MochaDone) => void, isCoreTest: boolean, only?: boolean); + constructor(testName: string, test: (projectManager: tm.ProjectManager, targetPlatform: platform.IPlatform, done: MochaDone) => void, isCoreTest: boolean, options?: any); /** * Called to create the test suite by the initializeTests function * @@ -557,11 +428,7 @@ declare module 'code-push-plugin-testing-framework/script/test' { /** * Returns a default update response to give to the app in a checkForUpdate request */ - export function createMockResponse(mandatory?: boolean): su.CheckForUpdateResponseMock; - /** - * Returns a default update response with a download URL and random package hash. - */ - export function getMockResponse(targetPlatform: platform.IPlatform, mandatory?: boolean, randomHash?: boolean): su.CheckForUpdateResponseMock; + export function createUpdateResponse(mandatory?: boolean, targetPlatform?: platform.IPlatform, randomHash?: boolean): su.CheckForUpdateResponseMock; /** * Wrapper for ProjectManager.setupScenario */ @@ -571,9 +438,9 @@ declare module 'code-push-plugin-testing-framework/script/test' { */ export function createUpdate(projectManager: tm.ProjectManager, targetPlatform: platform.IPlatform, scenarioJsPath: string, version: string): Q.Promise; /** - * Waits for the next set of test messages sent by the app and asserts that they are equal to the expected messages + * Returns a promise that waits for the next set of test messages sent by the app and resolves if that they are equal to the expected messages or rejects if they are not. */ - export function verifyMessages(expectedMessages: (string | su.AppMessage)[], deferred: Q.Deferred): (requestBody: any) => void; + export function expectTestMessages(expectedMessages: (string | su.AppMessage)[]): Q.Promise; /** * Sets up the server that the test app uses to send test messages and check for and download updates. */ @@ -585,7 +452,58 @@ declare module 'code-push-plugin-testing-framework/script/test' { /** * Call this function with a ProjectManager and an array of TestBuilderDescribe objects to run tests */ - export function initializeTests(projectManager: tm.ProjectManager, tests: TestBuilderDescribe[]): void; + export function initializeTests(projectManager: tm.ProjectManager, tests: TestBuilderDescribe[], supportedTargetPlatforms: platform.IPlatform[]): void; + +} +declare module 'code-push-plugin-testing-framework/script/testUtil' { + import Q = require("q"); + export class TestUtil { + static ANDROID_KEY_PLACEHOLDER: string; + static IOS_KEY_PLACEHOLDER: string; + static SERVER_URL_PLACEHOLDER: string; + static INDEX_JS_PLACEHOLDER: string; + static CODE_PUSH_APP_VERSION_PLACEHOLDER: string; + static CODE_PUSH_TEST_APP_NAME_PLACEHOLDER: string; + static CODE_PUSH_APP_ID_PLACEHOLDER: string; + static PLUGIN_VERSION_PLACEHOLDER: string; + /** + * Reads a command line option passed to mocha and returns a default if unspecified. + */ + static readMochaCommandLineOption(optionName: string, defaultValue?: string): string; + /** + * Reads command line options passed to mocha. + */ + static readMochaCommandLineFlag(optionName: string): boolean; + /** + * Executes a child process and returns a promise that resolves with its output or rejects with its error. + */ + static getProcessOutput(command: string, options?: { + cwd?: string; + stdio?: any; + customFds?: any; + env?: any; + encoding?: string; + timeout?: number; + maxBuffer?: number; + killSignal?: string; + }, logStdOut?: boolean, logStdErr?: boolean): Q.Promise; + /** + * Returns the name of the plugin that is being tested. + */ + static getPluginName(): string; + /** + * Replaces a regex in a file with a given string. + */ + static replaceString(filePath: string, regex: string, replacement: string): void; + /** + * Copies a file from a given location to another. + */ + static copyFile(source: string, destination: string, overwrite: boolean): Q.Promise; + /** + * Archives the contents of targetFolder and puts it in an archive at archivePath. + */ + static archiveFolder(targetFolder: string, archivePath: string, isDiff: boolean): Q.Promise; + } } declare module 'code-push-plugin-testing-framework/script/index' { @@ -593,7 +511,7 @@ declare module 'code-push-plugin-testing-framework/script/index' { import * as PluginTestingFramework from 'code-push-plugin-testing-framework/script/test'; import { ProjectManager } from 'code-push-plugin-testing-framework/script/projectManager'; import * as ServerUtil from 'code-push-plugin-testing-framework/script/serverUtil'; - import * as TestUtil from 'code-push-plugin-testing-framework/script/testUtil'; + import { TestUtil } from 'code-push-plugin-testing-framework/script/testUtil'; export { Platform, PluginTestingFramework, ProjectManager, ServerUtil, TestUtil }; }