Browse Source

[SauceLabs] Parameterized the config.

Andy Li 10 years ago
parent
commit
80542dfc34
3 changed files with 115 additions and 50 deletions
  1. 1 0
      .gitignore
  2. 1 1
      tests/RunCi.hx
  3. 113 49
      tests/unit/src/RunSauceLabs.hx

+ 1 - 0
.gitignore

@@ -52,6 +52,7 @@
 /tests/unit/native_cs/native_cs.csproj
 /tests/unit/unit.js.map
 /tests/unit/unit.n
+/tests/unit/node_modules/
 
 /haxe.sublime*
 build.bat

+ 1 - 1
tests/RunCi.hx

@@ -529,7 +529,7 @@ class RunCi {
 						haxelibInstallGit("dionjwa", "nodejs-std", "master", "src", true, "nodejs");
 						runCommand("haxe", ["compile-saucelabs-runner.hxml"]);
 						var server = new Process("nekotools", ["server"]);
-						runCommand("node", ["bin/RunSauceLabs.js"]);
+						runCommand("node", ["bin/RunSauceLabs.js", "unit-js.html"]);
 						server.close();
 					}
 

+ 113 - 49
tests/unit/src/RunSauceLabs.hx

@@ -1,7 +1,31 @@
+import haxe.Constraints;
+import haxe.*;
 import js.Node.*;
 using Reflect;
 using Lambda;
 
+/**
+	Promise interface of [Q](https://github.com/kriskowal/q).
+	Incomplete.
+*/
+private typedef Promise = {
+	public function then(onResolve:Function, ?onReject:Function):Promise;
+	public function fail(onReject:Function):Promise;
+}
+
+/**
+	Run tests on SauceLabs.
+
+	Usage: npm install wd q && node RunSauceLabs.js testFile.html [...testFile2.html] [options]
+	Options:
+		-serve-domain <domain>		Domain of the server that serves the test files. Default: localhost
+		-serve-port	<port>			Port number of the server that serves the test files. Default: 2000
+		-connect-domain <domain>	Domain of the remote testing server. Default: localhost (using Sauce Connect)
+		-connect-port <port>		Port number of remote testing server. Default: 4445 (using Sauce Connect)
+		-browsers <browsers>		A list of browsers to test with in JSON format. Default: refer to source code
+
+	Tests should log "SUCCESS: true" or "SUCCESS: false" to the console when it is done.
+*/
 class RunSauceLabs {
 	static function successMsg(msg:String):Void {
 		console.log('\x1b[32m' + msg + '\x1b[0m');
@@ -14,19 +38,11 @@ class RunSauceLabs {
 	}
 
 	static function main():Void {
-		var allSuccess = true;
-		var q:Dynamic = require("q");
-		var webdriver:Dynamic = require("wd");
-		var browser:Dynamic = webdriver.promiseRemote(
-			"localhost",
-			4445,
-			Sys.getEnv("SAUCE_USERNAME"),
-			Sys.getEnv("SAUCE_ACCESS_KEY")
-		);
-
-		var tags = [];
-		if (Sys.getEnv("TRAVIS") != null)
-			tags.push("TravisCI");
+		var serveDomain = "localhost";
+		var servePort = "2000";
+		var connectDomain = "localhost";
+		var connectPort = "4445";
+		var urls = [];
 
 		//https://saucelabs.com/platforms
 		var browsers:Array<Dynamic> = [
@@ -94,6 +110,12 @@ class RunSauceLabs {
 				"version": "6.1",
 				"device-orientation": "portrait"
 			},
+			{
+				"browserName": "iphone",
+				"platform": "OS X 10.9",
+				"version": "8.1",
+				"device-orientation": "portrait"
+			},
 			{
 				"browserName": "android",
 				"platform": "Linux",
@@ -108,11 +130,44 @@ class RunSauceLabs {
 			}
 		];
 
+		var arg, args = process.argv.slice(2);
+		while ((arg = args.shift()) != null) {
+			switch (arg) {
+				case "-serve-domain":
+					serveDomain = args.shift();
+				case "-serve-port":
+					servePort = args.shift();
+				case "-connect-domain":
+					connectDomain = args.shift();
+				case "-connect-port":
+					connectPort = args.shift();
+				case "-browsers":
+					browsers = Json.parse(args.shift());
+				case _:
+					urls.push(arg);
+			}
+		}
+
+		var allSuccess = true;
+		var q:Dynamic = require("q");
+		var webdriver:Dynamic = require("wd");
+		var browser:Dynamic = webdriver.promiseRemote(
+			connectDomain,
+			connectPort,
+			Sys.getEnv("SAUCE_USERNAME"),
+			Sys.getEnv("SAUCE_ACCESS_KEY")
+		);
+
+		var tags = [];
+		if (Sys.getEnv("TRAVIS") != null)
+			tags.push("TravisCI");
+
 		var timeout = 30000; //30s
 
 		function testBrowser(caps:Dynamic, trials = 3):Dynamic {
 			console.log('========================================================');
-			console.log('Requesting: ${caps.browserName} ${caps.version} on ${caps.platform}');
+			var browserName = caps.hasField("version") ? '${caps.browserName} ${caps.version}' : caps.browserName;
+			console.log('Requesting: ${browserName} on ${caps.platform}');
 
 			caps.setField("name", Sys.getEnv("TRAVIS") != null ? Sys.getEnv("TRAVIS_REPO_SLUG") : "haxe");
 			caps.setField("tags", tags);
@@ -124,7 +179,8 @@ class RunSauceLabs {
 			trials--;
 
 			function onErrored(err):Dynamic {
-				console.log(err);
+				console.log(Std.string(err));
+				console.log("detail: " + Json.stringify(err, "  "));
 				if (trials > 0) {
 					return browser
 						.sauceJobUpdate({ passed: true, tags: tags.concat(["errored"]) })
@@ -150,6 +206,8 @@ class RunSauceLabs {
 					);
 			}
 
+			var browserSuccess = true;
+
 			return browser
 				.init(caps)
 				.then(function() {
@@ -162,47 +220,53 @@ class RunSauceLabs {
 				.then(function()
 					return browser.setAsyncScriptTimeout(timeout))
 				.then(function(){
-					console.log("[debug] opening test page");
-					return browser.get("http://localhost:2000/unit-js.html");
-				})
-				.then(function() {
-					console.log("[debug] waiting for test to exit");
-					return 
-						until("return (typeof unit != 'undefined') && unit.Test && (typeof unit.Test.success === 'boolean')")
-						.timeout(timeout);
-				})
-				.then(function() {
-					console.log("[debug] test exited");
-					return browser.text("body");
-				})
-				.then(function(resultText:String) {
-					//check if test is successful or not
-					var success = false;
-					for (line in resultText.split("\n")) {
-						infoMsg(line);
-						if (line.indexOf("SUCCESS: ") >= 0) {
-							success = line.indexOf("SUCCESS: true") >= 0;
-							break;
-						}
-					}
-					allSuccess = allSuccess && success;
-
-					if (success) {
-						successMsg('${caps.browserName} ${caps.version} on ${caps.platform}: SUCCESS');
-					} else {
-						failMsg('${caps.browserName} ${caps.version} on ${caps.platform}: FAIL');
-					}
-
-					return browser.sauceJobUpdate({ passed: success });
+					return urls.fold(function(url:String, promise:Promise):Promise {
+						return promise.then(function(){
+							var url = 'http://${serveDomain}:${servePort}/${url}';
+							console.log('[debug] opening $url');
+							return browser.get(url)
+								.then(function() {
+									console.log("[debug] waiting for test to exit");
+									return 
+										until("return (typeof unit != 'undefined') && unit.Test && (typeof unit.Test.success === 'boolean')")
+										.timeout(timeout);
+								})
+								.then(function() {
+									console.log("[debug] test exited");
+									return browser.text("body");
+								})
+								.then(function(resultText:String) {
+									//check if test is successful or not
+									var success = false;
+									for (line in resultText.split("\n")) {
+										infoMsg(line);
+										if (line.indexOf("SUCCESS: ") >= 0) {
+											success = line.indexOf("SUCCESS: true") >= 0;
+											break;
+										}
+									}
+									browserSuccess = browserSuccess && success;
+									allSuccess = allSuccess && browserSuccess;
+
+									if (success) {
+										successMsg('$url in ${caps.browserName} ${caps.version} on ${caps.platform}: SUCCESS');
+									} else {
+										failMsg('$url in ${caps.browserName} ${caps.version} on ${caps.platform}: FAIL');
+									}
+								})
+								.timeout(60000 * 5); //5 min
+						});
+					}, q());
 				})
+				.then(function()
+					return browser.sauceJobUpdate({ passed: browserSuccess }))
 				.then(function()
 					return browser.quit())
-				.timeout(60000 * 5) //5 min
 				.fail(onErrored);
 		}
 
 		browsers
-			.fold(function(caps:Dynamic, promise:Dynamic):Dynamic {
+			.fold(function(caps:Dynamic, promise:Promise):Promise {
 				return promise.then(function () return testBrowser(caps));
 			}, q())
 			.then(function() {