diff --git a/packages/server/lib/controllers/spec.js b/packages/server/lib/controllers/spec.js index 7ea59be2b1..910bb46387 100644 --- a/packages/server/lib/controllers/spec.js +++ b/packages/server/lib/controllers/spec.js @@ -1,56 +1,66 @@ -debug = require("debug")("cypress:server:controllers:spec") -Promise = require("bluebird") -errors = require("../errors") -preprocessor = require("../plugins/preprocessor") +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * DS207: Consider shorter variations of null checks + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const debug = require("debug")("cypress:server:controllers:spec"); +const Promise = require("bluebird"); +const errors = require("../errors"); +const preprocessor = require("../plugins/preprocessor"); module.exports = { - handle: (spec, req, res, config, next, project) -> - debug("request for %o", { spec }) + handle(spec, req, res, config, next, project) { + debug("request for %o", { spec }); res.set({ - "Cache-Control": "no-cache, no-store, must-revalidate" - "Pragma": "no-cache" + "Cache-Control": "no-cache, no-store, must-revalidate", + "Pragma": "no-cache", "Expires": "0" - }) + }); - res.type("js") + res.type("js"); - preprocessor + return preprocessor .getFile(spec, config) - .then (filePath) -> - debug("sending spec %o", { filePath }) - sendFile = Promise.promisify(res.sendFile.bind(res)) - sendFile(filePath) - .catch { code: "ECONNABORTED" }, (err) -> - ## https://github.com/cypress-io/cypress/issues/1877 - ## now that we are properly catching errors from - ## res.sendFile, sendFile will reject if the browser aborts - ## its internal requests (as it shuts down) with - ## ECONNABORTED. This happens because if a previous spec - ## file is unable to be transpiled correctly, we immediately - ## shut down the run, which closes the browser, triggering - ## the browser to abort the request which would end up here - ## and display two different errors. - return - .catch (err) -> - if config.isTextTerminal - ## bluebird made a change in 3.4.7 where they handle - ## SyntaxErrors differently here - ## https://github.com/petkaantonov/bluebird/pull/1295 - ## - ## their new behavior messes up how we show these errors - ## so we must backup the original stack and replace it here - if os = err.originalStack - err.stack = os + .then(function(filePath) { + debug("sending spec %o", { filePath }); + const sendFile = Promise.promisify(res.sendFile.bind(res)); + return sendFile(filePath);}).catch({ code: "ECONNABORTED" }, function(err) { + //# https://github.com/cypress-io/cypress/issues/1877 + //# now that we are properly catching errors from + //# res.sendFile, sendFile will reject if the browser aborts + //# its internal requests (as it shuts down) with + //# ECONNABORTED. This happens because if a previous spec + //# file is unable to be transpiled correctly, we immediately + //# shut down the run, which closes the browser, triggering + //# the browser to abort the request which would end up here + //# and display two different errors. + + }).catch(function(err) { + if (config.isTextTerminal) { + //# bluebird made a change in 3.4.7 where they handle + //# SyntaxErrors differently here + //# https://github.com/petkaantonov/bluebird/pull/1295 + //# + //# their new behavior messes up how we show these errors + //# so we must backup the original stack and replace it here + let os; + if (os = err.originalStack) { + err.stack = os; + } - filePath = err.filePath ? spec + const filePath = err.filePath != null ? err.filePath : spec; - err = errors.get("BUNDLE_ERROR", filePath, preprocessor.errorMessage(err)) + err = errors.get("BUNDLE_ERROR", filePath, preprocessor.errorMessage(err)); - console.log("") - errors.log(err) + console.log(""); + errors.log(err); - project.emit("exitEarlyWithErr", err.message) - else - res.send(preprocessor.clientSideError(err)) -} + return project.emit("exitEarlyWithErr", err.message); + } else { + return res.send(preprocessor.clientSideError(err)); + } + }); + } +}; diff --git a/packages/server/lib/routes.js b/packages/server/lib/routes.js index 0883990d7d..b798a545bb 100644 --- a/packages/server/lib/routes.js +++ b/packages/server/lib/routes.js @@ -1,84 +1,86 @@ -path = require("path") -la = require("lazy-ass") -check = require("check-more-types") -debug = require("debug")("cypress:server:routes") +/* + * decaffeinate suggestions: + * DS102: Remove unnecessary code created because of implicit returns + * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md + */ +const path = require("path"); +const la = require("lazy-ass"); +const check = require("check-more-types"); +const debug = require("debug")("cypress:server:routes"); -CacheBuster = require("./util/cache_buster") -cwd = require("./cwd") -logger = require("./logger") -spec = require("./controllers/spec") -reporter = require("./controllers/reporter") -runner = require("./controllers/runner") -xhrs = require("./controllers/xhrs") -client = require("./controllers/client") -files = require("./controllers/files") -staticCtrl = require("./controllers/static") +const CacheBuster = require("./util/cache_buster"); +const cwd = require("./cwd"); +const logger = require("./logger"); +const spec = require("./controllers/spec"); +const reporter = require("./controllers/reporter"); +const runner = require("./controllers/runner"); +const xhrs = require("./controllers/xhrs"); +const client = require("./controllers/client"); +const files = require("./controllers/files"); +const staticCtrl = require("./controllers/static"); -module.exports = (app, config, request, getRemoteState, getDeferredResponse, project, networkProxy) -> - ## routing for the actual specs which are processed automatically - ## this could be just a regular .js file or a .coffee file - app.get "/__cypress/tests", (req, res, next) -> - ## slice out the cache buster - test = CacheBuster.strip(req.query.p) +module.exports = function(app, config, request, getRemoteState, getDeferredResponse, project, networkProxy) { + //# routing for the actual specs which are processed automatically + //# this could be just a regular .js file or a .coffee file + app.get("/__cypress/tests", function(req, res, next) { + //# slice out the cache buster + const test = CacheBuster.strip(req.query.p); - spec.handle(test, req, res, config, next, project) + return spec.handle(test, req, res, config, next, project); + }); - app.get "/__cypress/socket.io.js", (req, res) -> - client.handle(req, res) + app.get("/__cypress/socket.io.js", (req, res) => client.handle(req, res)); - app.get "/__cypress/reporter/*", (req, res) -> - reporter.handle(req, res) + app.get("/__cypress/reporter/*", (req, res) => reporter.handle(req, res)); - app.get "/__cypress/runner/*", (req, res) -> - runner.handle(req, res) + app.get("/__cypress/runner/*", (req, res) => runner.handle(req, res)); - app.get "/__cypress/static/*", (req, res) -> - staticCtrl.handle(req, res) + app.get("/__cypress/static/*", (req, res) => staticCtrl.handle(req, res)); - ## routing for /files JSON endpoint - app.get "/__cypress/files", (req, res) -> - files.handleFiles(req, res, config) + //# routing for /files JSON endpoint + app.get("/__cypress/files", (req, res) => files.handleFiles(req, res, config)); - ## routing for the dynamic iframe html - app.get "/__cypress/iframes/*", (req, res) -> - files.handleIframe(req, res, config, getRemoteState) + //# routing for the dynamic iframe html + app.get("/__cypress/iframes/*", (req, res) => files.handleIframe(req, res, config, getRemoteState)); - app.all "/__cypress/xhrs/*", (req, res, next) -> - xhrs.handle(req, res, getDeferredResponse, config, next) + app.all("/__cypress/xhrs/*", (req, res, next) => xhrs.handle(req, res, getDeferredResponse, config, next)); - app.get "/__root/*", (req, res, next) -> - file = path.join(config.projectRoot, req.params[0]) + app.get("/__root/*", function(req, res, next) { + const file = path.join(config.projectRoot, req.params[0]); - res.sendFile(file, {etag: false}) + return res.sendFile(file, {etag: false}); + }); - ## we've namespaced the initial sending down of our cypress - ## app as '__' this route shouldn't ever be used by servers - ## and therefore should not conflict - ## --- - ## TODO: we should additionally send config for the socket.io route, etc - ## and any other __cypress namespaced files so that the runner does - ## not have to be aware of anything - la(check.unemptyString(config.clientRoute), "missing client route in config", config) + //# we've namespaced the initial sending down of our cypress + //# app as '__' this route shouldn't ever be used by servers + //# and therefore should not conflict + //# --- + //# TODO: we should additionally send config for the socket.io route, etc + //# and any other __cypress namespaced files so that the runner does + //# not have to be aware of anything + la(check.unemptyString(config.clientRoute), "missing client route in config", config); - app.get config.clientRoute, (req, res) -> - debug("Serving Cypress front-end by requested URL:", req.url) + app.get(config.clientRoute, function(req, res) { + debug("Serving Cypress front-end by requested URL:", req.url); - runner.serve(req, res, { + return runner.serve(req, res, { config, project, getRemoteState, - }) + }); + }); - app.all "*", (req, res, next) -> - networkProxy.handleHttpRequest(req, res) + app.all("*", (req, res, next) => networkProxy.handleHttpRequest(req, res)); - ## when we experience uncaught errors - ## during routing just log them out to - ## the console and send 500 status - ## and report to raygun (in production) - app.use (err, req, res, next) -> - console.log err.stack + //# when we experience uncaught errors + //# during routing just log them out to + //# the console and send 500 status + //# and report to raygun (in production) + return app.use(function(err, req, res, next) { + console.log(err.stack); - res.set("x-cypress-error", err.message) - res.set("x-cypress-stack", JSON.stringify(err.stack)) - res.sendStatus(500) + res.set("x-cypress-error", err.message); + res.set("x-cypress-stack", JSON.stringify(err.stack)); + return res.sendStatus(500); + }); +};