diff --git a/.gitignore b/.gitignore index 0c89e2c191..ec7bcdde72 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ node_modules *.orig dist dist-* +.vscode diff --git a/packages/server/lib/controllers/spec.coffee b/packages/server/lib/controllers/spec.coffee index 550659629f..384ff23fa3 100644 --- a/packages/server/lib/controllers/spec.coffee +++ b/packages/server/lib/controllers/spec.coffee @@ -14,7 +14,8 @@ module.exports = { res.type("js") streamBundle = -> - fs.createReadStream(bundle.outputPath(config.projectName, spec)) + bundledPath = bundle.outputPath(config.projectRoot, spec) + fs.createReadStream(bundledPath) .pipe(res) if config.isHeadless diff --git a/packages/server/lib/log.coffee b/packages/server/lib/log.coffee index 222081a218..4f0f89bd25 100644 --- a/packages/server/lib/log.coffee +++ b/packages/server/lib/log.coffee @@ -6,4 +6,8 @@ # use # log = require('./log') # log('working in %s', process.cwd()) +# If you need a logger that might be very specific +# you can construct it yourself, just make sure +# to prefix label with "cypress:server:", for example +# log = require('debug')('cypress:server:bundle') module.exports = require('debug')('cypress:server') diff --git a/packages/server/lib/util/bundle.coffee b/packages/server/lib/util/bundle.coffee index 31d3811417..5eec87f005 100644 --- a/packages/server/lib/util/bundle.coffee +++ b/packages/server/lib/util/bundle.coffee @@ -11,9 +11,10 @@ presetReact = require("babel-preset-react") presetLatest = require("babel-preset-latest") stringStream = require("string-to-stream") pluginAddModuleExports = require("babel-plugin-add-module-exports") -sanitize = require("sanitize-filename") cjsxify = require("./cjsxify") appData = require("./app_data") +{ toHashName } = require('./saved_state') +log = require('debug')('cypress:server:bundle') fs = Promise.promisifyAll(fs) @@ -24,16 +25,19 @@ module.exports = { reset: -> builtFiles = {} - outputPath: (projectName = "", filePath) -> - appData.path("bundles", sanitize(projectName), filePath) + outputPath: (projectRoot = "", filePath) -> + appData.path(toHashName(projectRoot), "bundles", filePath) build: (filePath, config) -> if config.isHeadless and built = builtFiles[filePath] return built + log "bundler for project #{config.projectRoot}" + emitter = new EE() absolutePath = path.join(config.projectRoot, filePath) + log "input absolute path #{absolutePath}" bundler = browserify({ entries: [absolutePath] @@ -58,7 +62,8 @@ module.exports = { bundle = => new Promise (resolve, reject) => - outputPath = @outputPath(config.projectName, filePath) + outputPath = @outputPath(config.projectRoot, filePath) + log "making bundle #{outputPath}" ## TODO: only ensure directory when first run and not on updates? fs.ensureDirAsync(path.dirname(outputPath)) .then => diff --git a/packages/server/lib/util/saved_state.coffee b/packages/server/lib/util/saved_state.coffee index 663a66020f..31dd367a41 100644 --- a/packages/server/lib/util/saved_state.coffee +++ b/packages/server/lib/util/saved_state.coffee @@ -1,11 +1,13 @@ log = require('../log') fs = require('fs') -path = require('path') +{ basename, join, isAbsolute } = require('path') md5 = require('md5') +sanitize = require("sanitize-filename") toHashName = (projectPath) -> throw new Error("Missing project path") unless projectPath - name = path.basename(projectPath) + throw new Error("Expected project absolute path, not just a name #{projectPath}") unless isAbsolute(projectPath) + name = sanitize(basename(projectPath)) hash = md5(projectPath) "#{name}-#{hash}" @@ -15,14 +17,15 @@ formStatePath = (projectPath) -> log('for project path %s', projectPath) else log('missing project path, looking for project here') - cypressJsonPath = path.join(process.cwd(), 'cypress.json') + cypressJsonPath = join(process.cwd(), 'cypress.json') if fs.existsSync(cypressJsonPath) log('found cypress file %s', cypressJsonPath) projectPath = process.cwd() statePath = "state.json" if projectPath - statePath = path.join(toHashName(projectPath), statePath) + log "state path for project #{projectPath}" + statePath = join(toHashName(projectPath), statePath) return statePath diff --git a/packages/server/test/unit/saved_state_spec.coffee b/packages/server/test/unit/saved_state_spec.coffee index 02530a69f2..b3536791f9 100644 --- a/packages/server/test/unit/saved_state_spec.coffee +++ b/packages/server/test/unit/saved_state_spec.coffee @@ -44,11 +44,11 @@ describe "lib/saved_state", -> expect(statePath).to.equal(expected) it "caches state file instance per path", -> - a = savedState("foo/bar") - b = savedState("foo/bar") + a = savedState("/foo/bar") + b = savedState("/foo/bar") expect(a).to.equal(b) it "returns different state file for different path", -> - a = savedState("foo/bar") - b = savedState("foo/baz") + a = savedState("/foo/bar") + b = savedState("/foo/baz") expect(a).to.not.equal(b) diff --git a/packages/server/test/unit/spec_spec.coffee b/packages/server/test/unit/spec_spec.coffee index 79ad057ed9..10c6ac2021 100644 --- a/packages/server/test/unit/spec_spec.coffee +++ b/packages/server/test/unit/spec_spec.coffee @@ -43,10 +43,13 @@ browserifyFile = (filePath) -> ) describe "lib/controllers/spec", -> + specName = "sample.js" + specSource = ";" + beforeEach -> @config = { projectName: "foo?bar" - projectRoot: "" + projectRoot: "/foobar" integrationFolder: fixturesRoot browserify: { basedir: fixturesRoot @@ -67,14 +70,15 @@ describe "lib/controllers/spec", -> watchBundle: -> Promise.resolve() } - fs.ensureDirSync(appData.path("bundles", "foobar")) - fs.writeFileSync(appData.path("bundles", "foobar", "sample.js"), ';') + samplePath = bundle.outputPath(@config.projectRoot, specName) + fs.ensureDirSync(path.dirname(samplePath)) + fs.writeFileSync(samplePath, ';') @handle = (filePath) => spec.handle filePath, {}, @res, @config, (=>), @watchers, @project it "sets the correct content type", -> - @handle("sample.js") + @handle(specName) expect(@res.type) .to.have.been.calledOnce @@ -83,15 +87,15 @@ describe "lib/controllers/spec", -> describe "headed mode", -> it "sends the file from the bundles path", -> - @handle("sample.js") + @handle(specName) collectResponse(@res).then (result) -> - expect(result).to.equal(";") + expect(result).to.equal(specSource) it "sends the client-side error if there is one", -> @watchers.watchBundle = -> Promise.reject(new Error("Reason request failed")) - @handle("sample.js").then => + @handle(specName).then => expect(@res.send).to.have.been.called expect(@res.send.firstCall.args[0]).to.include("(function") expect(@res.send.firstCall.args[0]).to.include("Reason request failed") @@ -104,10 +108,10 @@ describe "lib/controllers/spec", -> @config.isHeadless = true it "sends the file from the bundles path", -> - @handle("sample.js") + @handle(specName) collectResponse(@res).then (result) -> - expect(result).to.equal(";") + expect(result).to.equal(specSource) it "logs the error and exits if there is one", -> err = new Error("Reason request failed") @@ -117,7 +121,7 @@ describe "lib/controllers/spec", -> }) @log = @sandbox.stub(errors, "log") - @handle("sample.js").then => + @handle(specName).then => expect(@log).to.have.been.called expect(@log.firstCall.args[0].stack).to.include("Oops...we found an error preparing this test file") expect(@project.emit).to.have.been.calledWithMatch("exitEarlyWithErr", "Oops...we found an error preparing this test file")