From 9752d02748aeab6922e64882617fe4c15da853be Mon Sep 17 00:00:00 2001 From: Martin von Gagern Date: Wed, 15 Jul 2015 00:46:38 +0200 Subject: [PATCH] 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. --- dockers/Screenshotter/README.md | 8 +-- dockers/Screenshotter/screenshotter.js | 72 ++++++++++++++++++++++---- server.js | 12 +++-- 3 files changed, 74 insertions(+), 18 deletions(-) diff --git a/dockers/Screenshotter/README.md b/dockers/Screenshotter/README.md index f491921..a4de12b 100644 --- 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 index 186ba36..5789bb1 100644 --- 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 index b57e7f9..ed5c20e 100644 --- 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;