mirror of
https://github.com/cypress-io/cypress.git
synced 2026-02-09 00:30:16 -06:00
140 lines
3.6 KiB
JavaScript
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
|