commit 9752d02748aeab6922e64882617fe4c15da853be
parent a18db362968b181c143e09abed970ace40c55182
Author: Martin von Gagern <gagern@ma.tum.de>
Date: Wed, 15 Jul 2015 00:46:38 +0200
Automatically start a development server
This avoids one of the few requirements we have left: you no longer have to
start a KaTeX development server, the script will do it for you, using a
random port number.
To reproduce the old behaviour, explicitely state --katex-port=7936.
Diffstat:
3 files changed, 74 insertions(+), 18 deletions(-)
diff --git a/dockers/Screenshotter/README.md b/dockers/Screenshotter/README.md
@@ -4,12 +4,8 @@
Now you too can generate screenshots from your own computer, and (hopefully)
have them look mostly the same as the current ones! Make sure you have docker
-installed and running. Also make sure that the development server is running,
-or start it by running
-
- node server.js
-
-in the top level directory of the source tree. If all you want is (re)create
+installed and running.
+If all you want is (re)create
all the snapshots for all the browsers, then you can do so by running the
`screenshotter.sh` script:
diff --git a/dockers/Screenshotter/screenshotter.js b/dockers/Screenshotter/screenshotter.js
@@ -2,10 +2,12 @@
var childProcess = require("child_process");
var fs = require("fs");
+var http = require("http");
var path = require("path");
var net = require("net");
var selenium = require("selenium-webdriver");
+var app = require("../../server");
var data = require("../../test/screenshotter/ss_data.json");
var dstDir = path.normalize(
@@ -49,7 +51,6 @@ var opts = require("nomnom")
})
.option("katexPort", {
full: "katex-port",
- "default": 7936,
help: "Port number of the KaTeX development server"
})
.option("include", {
@@ -76,10 +77,11 @@ if (opts.exclude) {
}
var seleniumURL = opts.seleniumURL;
-var katexURL = opts.katexURL;
var seleniumIP = opts.seleniumIP;
var seleniumPort = opts.seleniumPort;
+var katexURL = opts.katexURL;
var katexIP = opts.katexIP;
+var katexPort = opts.katexPort;
//////////////////////////////////////////////////////////////////////
// Work out connection to selenium docker container
@@ -128,17 +130,54 @@ if (seleniumURL) {
console.log("Selenium driver in local session");
}
-if (!katexURL) {
- katexURL = "http://" + katexIP + ":" + opts.katexPort + "/";
-}
var toStrip = "http://localhost:7936/"; // remove this from testcase URLs
+process.nextTick(startServer);
+var attempts = 0;
+
+//////////////////////////////////////////////////////////////////////
+// Start up development server
+
+var devServer = null;
+var minPort = 32768;
+var maxPort = 61000;
+
+function startServer() {
+ if (katexURL || katexPort) {
+ process.nextTick(tryConnect);
+ return;
+ }
+ var port = Math.floor(Math.random() * (maxPort - minPort)) + minPort;
+ var server = http.createServer(app).listen(port);
+ server.once("listening", function() {
+ devServer = server;
+ katexPort = port;
+ attempts = 0;
+ process.nextTick(tryConnect);
+ });
+ server.on("error", function(err) {
+ if (devServer !== null) { // error after we started listening
+ throw err;
+ } else if (++attempts > 50) {
+ throw new Error("Failed to start up dev server");
+ } else {
+ process.nextTick(startServer);
+ }
+ });
+}
+
//////////////////////////////////////////////////////////////////////
// Wait for container to become ready
-var attempts = 0;
-process.nextTick(seleniumIP ? tryConnect : buildDriver);
function tryConnect() {
+ if (!katexURL) {
+ katexURL = "http://" + katexIP + ":" + katexPort + "/";
+ console.log("KaTeX URL is " + katexURL);
+ }
+ if (!seleniumIP) {
+ process.nextTick(buildDriver);
+ return;
+ }
var sock = net.connect({
host: seleniumIP,
port: +seleniumPort
@@ -146,7 +185,7 @@ function tryConnect() {
sock.on("connect", function() {
sock.end();
attempts = 0;
- setTimeout(buildDriver, 0);
+ process.nextTick(buildDriver);
}).on("error", function() {
if (++attempts > 50) {
throw new Error("Failed to connect selenium server.");
@@ -202,6 +241,8 @@ function imageDimensions(img) {
//////////////////////////////////////////////////////////////////////
// Take the screenshots
+var countdown = listOfCases.length;
+
function takeScreenshots() {
listOfCases.forEach(takeScreenshot);
}
@@ -231,7 +272,20 @@ function takeScreenshot(key) {
key += "_alt";
}
var file = path.join(dstDir, key + "-" + opts.browser + ".png");
- fs.writeFile(file, img.buf, check);
+ var deferred = new selenium.promise.Deferred();
+ fs.writeFile(file, img.buf, function(err) {
+ if (err) {
+ deferred.reject(err);
+ } else {
+ deferred.fulfill();
+ }
+ });
+ return deferred.promise;
+ }).then(function() {
console.log(key);
+ if (--countdown === 0) {
+ // devServer.close(cb) will take too long.
+ process.exit(0);
+ }
}, check);
}
diff --git a/server.js b/server.js
@@ -7,7 +7,9 @@ var less = require("less");
var app = express();
-app.use(express.logger());
+if (require.main === module) {
+ app.use(express.logger());
+}
var serveBrowserified = function(file, standaloneName) {
return function(req, res, next) {
@@ -69,5 +71,9 @@ app.use(function(err, req, res, next) {
res.send(500, err.stack);
});
-app.listen(7936);
-console.log("Serving on http://0.0.0.0:7936/ ...");
+if (require.main === module) {
+ app.listen(7936);
+ console.log("Serving on http://0.0.0.0:7936/ ...");
+}
+
+module.exports = app;