Files
cypress/packages/server/lib/plugins/preprocessor.js
decaffeinate c7dd989893 decaffeinate: Rename api.coffee and 35 other files from .coffee to .js
decaffeinate: Rename reporter.coffee from .coffee to .js
2020-06-04 14:02:58 -04:00

140 lines
3.6 KiB
JavaScript

_ = require("lodash")
EE = require("events")
path = require("path")
debug = require("debug")("cypress:server:preprocessor")
Promise = require("bluebird")
appData = require("../util/app_data")
cwd = require("../cwd")
plugins = require("../plugins")
resolve = require("./resolve")
errorMessage = (err = {}) ->
(err.stack ? err.annotated ? err.message ? err.toString())
## strip out stack noise from parser like
## at Parser.pp$5.raise (/path/to/node_modules/babylon/lib/index.js:4215:13)
.replace(/\n\s*at.*/g, "")
.replace(/From previous event:\n?/g, "")
clientSideError = (err) ->
console.log(err.message)
err = errorMessage(err)
"""
(function () {
Cypress.action("spec:script:error", {
type: "BUNDLE_ERROR",
error: #{JSON.stringify(err)}
})
}())
"""
baseEmitter = new EE()
fileObjects = {}
fileProcessors = {}
createBrowserifyPreprocessor = (options) ->
debug("creating browserify preprocessor with options %o", options)
browserify = require("@cypress/browserify-preprocessor")
browserify(options)
setDefaultPreprocessor = (config) ->
debug("set default preprocessor")
tsPath = resolve.typescript(config)
options = {
typescript: tsPath
}
plugins.register("file:preprocessor", API.createBrowserifyPreprocessor(options))
plugins.registerHandler (ipc) ->
ipc.on "preprocessor:rerun", (filePath) ->
debug("ipc preprocessor:rerun event")
baseEmitter.emit("file:updated", filePath)
baseEmitter.on "close", (filePath) ->
debug("base emitter plugin close event")
ipc.send("preprocessor:close", filePath)
# for simpler stubbing from unit tests
API = {
errorMessage
clientSideError
setDefaultPreprocessor
createBrowserifyPreprocessor
emitter: baseEmitter
getFile: (filePath, config) ->
debug("getting file #{filePath}")
filePath = path.resolve(config.projectRoot, filePath)
debug("getFile #{filePath}")
if not fileObject = fileObjects[filePath]
## we should be watching the file if we are NOT
## in a text terminal aka cypress run
## TODO: rename this to config.isRunMode
## vs config.isInterativeMode
shouldWatch = not config.isTextTerminal or Boolean(process.env.CYPRESS_INTERNAL_FORCE_FILEWATCH)
baseFilePath = filePath
.replace(config.projectRoot, "")
.replace(config.integrationFolder, "")
fileObject = fileObjects[filePath] = _.extend(new EE(), {
filePath,
shouldWatch,
outputPath: appData.getBundledFilePath(config.projectRoot, baseFilePath)
})
fileObject.on "rerun", ->
debug("file object rerun event")
baseEmitter.emit("file:updated", filePath)
baseEmitter.once "close", ->
debug("base emitter native close event")
fileObject.emit("close")
if not plugins.has("file:preprocessor")
setDefaultPreprocessor(config)
if config.isTextTerminal and fileProcessor = fileProcessors[filePath]
debug("headless and already processed")
return fileProcessor
preprocessor = fileProcessors[filePath] = Promise.try ->
plugins.execute("file:preprocessor", fileObject)
return preprocessor
removeFile: (filePath, config) ->
filePath = path.resolve(config.projectRoot, filePath)
return if not fileProcessors[filePath]
debug("removeFile #{filePath}")
baseEmitter.emit("close", filePath)
if fileObject = fileObjects[filePath]
fileObject.emit("close")
delete fileObjects[filePath]
delete fileProcessors[filePath]
close: ->
debug("close preprocessor")
fileObjects = {}
fileProcessors = {}
baseEmitter.emit("close")
baseEmitter.removeAllListeners()
}
module.exports = API