From 55755e4a0b6529bc855d7dbfc7b04f0094e6aacc Mon Sep 17 00:00:00 2001 From: Peter Halliday Date: Mon, 27 Jun 2016 12:26:21 +0200 Subject: [PATCH] feat: upstreamProxy config option to deal with proxies that adjust the base path, etc --- client/constants.js | 1 + client/main.js | 6 +- docs/config/01-configuration-file.md | 38 ++++++++ lib/config.js | 45 +++++++-- lib/launcher.js | 11 ++- lib/middleware/karma.js | 22 +++-- test/e2e/steps/core_steps.js | 128 ++++++++++++++------------ test/e2e/support/after_hooks.js | 5 +- test/e2e/support/behind-proxy/plus.js | 5 + test/e2e/support/behind-proxy/test.js | 10 ++ test/e2e/support/proxy.js | 43 +++++++++ test/e2e/support/world.js | 2 + test/e2e/upstream-proxy.feature | 25 +++++ test/unit/config.spec.js | 30 ++++++ test/unit/launcher.spec.js | 42 +++++++++ test/unit/middleware/karma.spec.js | 36 ++++---- 16 files changed, 353 insertions(+), 96 deletions(-) create mode 100644 test/e2e/support/behind-proxy/plus.js create mode 100644 test/e2e/support/behind-proxy/test.js create mode 100644 test/e2e/support/proxy.js create mode 100644 test/e2e/upstream-proxy.feature diff --git a/client/constants.js b/client/constants.js index be678b5f7..0e8745395 100644 --- a/client/constants.js +++ b/client/constants.js @@ -1,5 +1,6 @@ module.exports = { VERSION: '%KARMA_VERSION%', KARMA_URL_ROOT: '%KARMA_URL_ROOT%', + KARMA_PROXY_PATH: '%KARMA_PROXY_PATH%', CONTEXT_URL: 'context.html' } diff --git a/client/main.js b/client/main.js index ed9200013..8f3cfee63 100644 --- a/client/main.js +++ b/client/main.js @@ -5,15 +5,17 @@ require('core-js/es5') var Karma = require('./karma') var StatusUpdater = require('./updater') var util = require('../common/util') +var constants = require('./constants') -var KARMA_URL_ROOT = require('./constants').KARMA_URL_ROOT +var KARMA_URL_ROOT = constants.KARMA_URL_ROOT +var KARMA_PROXY_PATH = constants.KARMA_PROXY_PATH // Connect to the server using socket.io http://socket.io var socket = io(location.host, { reconnectionDelay: 500, reconnectionDelayMax: Infinity, timeout: 2000, - path: '/' + KARMA_URL_ROOT.substr(1) + 'socket.io', + path: KARMA_PROXY_PATH + KARMA_URL_ROOT.substr(1) + 'socket.io', 'sync disconnect on unload': true }) diff --git a/docs/config/01-configuration-file.md b/docs/config/01-configuration-file.md index 09087bb95..9997907b5 100644 --- a/docs/config/01-configuration-file.md +++ b/docs/config/01-configuration-file.md @@ -647,6 +647,44 @@ is handed off to [socket.io](http://socket.io/) (which manages the communication between browsers and the testing server). +## upstreamProxy +**Type:** Object + +**Default:** `undefined` + +**Description:** For use when the Karma server needs to be run behind a proxy that changes the base url, etc + +If set then the following fields will be defined and can be overriden: + +### path +**Type:** String + +**Default:** `'/'` + +**Description:** Will be prepended to the base url when launching browsers and prepended to internal urls as loaded by the browsers + +### port +**Type:** Number + +**Default:** `9875` + +**Description:** Will be used as the port when launching browsers + +### hostname +**Type:** String + +**Default:** `'localhost'` + +**Description:** Will be used as the hostname when launching browsers + +### protocol +**Type:** String + +**Default:** `'http:'` + +**Description:** Will be used as the protocol when launching browsers + + ## urlRoot **Type:** String diff --git a/lib/config.js b/lib/config.js index 235c4bb75..e4988b998 100644 --- a/lib/config.js +++ b/lib/config.js @@ -72,17 +72,21 @@ var createPatternObject = function (pattern) { return new Pattern(null, false, false, false, false) } -var normalizeUrlRoot = function (urlRoot) { - var normalizedUrlRoot = urlRoot - - if (normalizedUrlRoot.charAt(0) !== '/') { - normalizedUrlRoot = '/' + normalizedUrlRoot +var normalizeUrl = function (url) { + if (url.charAt(0) !== '/') { + url = '/' + url } - if (normalizedUrlRoot.charAt(normalizedUrlRoot.length - 1) !== '/') { - normalizedUrlRoot = normalizedUrlRoot + '/' + if (url.charAt(url.length - 1) !== '/') { + url = url + '/' } + return url +} + +var normalizeUrlRoot = function (urlRoot) { + var normalizedUrlRoot = normalizeUrl(urlRoot) + if (normalizedUrlRoot !== urlRoot) { log.warn('urlRoot normalized to "%s"', normalizedUrlRoot) } @@ -90,6 +94,16 @@ var normalizeUrlRoot = function (urlRoot) { return normalizedUrlRoot } +var normalizeProxyPath = function (proxyPath) { + var normalizedProxyPath = normalizeUrl(proxyPath) + + if (normalizedProxyPath !== proxyPath) { + log.warn('proxyPath normalized to "%s"', normalizedProxyPath) + } + + return normalizedProxyPath +} + var normalizeConfig = function (config, configFilePath) { var basePathResolve = function (relativePath) { if (helper.isUrlAbsolute(relativePath)) { @@ -135,6 +149,22 @@ var normalizeConfig = function (config, configFilePath) { // normalize urlRoot config.urlRoot = normalizeUrlRoot(config.urlRoot) + // normalize and default upstream proxy settings if given + if (config.upstreamProxy) { + var proxy = config.upstreamProxy + proxy.path = _.isUndefined(proxy.path) ? '/' : normalizeProxyPath(proxy.path) + proxy.hostname = _.isUndefined(proxy.hostname) ? 'localhost' : proxy.hostname + proxy.port = _.isUndefined(proxy.port) ? 9875 : proxy.port + + // force protocol to end with ':' + proxy.protocol = (proxy.protocol || 'http').split(':')[0] + ':' + if (proxy.protocol.match(/https?:/) === null) { + log.warn('"%s" is not a supported upstream proxy protocol, defaulting to "http:"', + proxy.protocol) + proxy.protocol = 'http:' + } + } + // force protocol to end with ':' config.protocol = (config.protocol || 'http').split(':')[0] + ':' if (config.protocol.match(/https?:/) === null) { @@ -276,6 +306,7 @@ var Config = function () { this.proxyValidateSSL = true this.preprocessors = {} this.urlRoot = '/' + this.upstreamProxy = undefined this.reportSlowerThan = 0 this.loggers = [constant.CONSOLE_APPENDER] this.transports = ['polling', 'websocket'] diff --git a/lib/launcher.js b/lib/launcher.js index bca344400..67c0ebe56 100644 --- a/lib/launcher.js +++ b/lib/launcher.js @@ -39,9 +39,15 @@ var Launcher = function (server, emitter, injector) { return null } - this.launchSingle = function (protocol, hostname, port, urlRoot) { + this.launchSingle = function (protocol, hostname, port, urlRoot, upstreamProxy) { var self = this return function (name) { + if (upstreamProxy) { + protocol = upstreamProxy.protocol + hostname = upstreamProxy.hostname + port = upstreamProxy.port + urlRoot = upstreamProxy.path + urlRoot.substr(1) + } var url = protocol + '//' + hostname + ':' + port + urlRoot var locals = { @@ -158,7 +164,8 @@ var Launcher = function (server, emitter, injector) { 'config.protocol', 'config.hostname', 'config.port', - 'config.urlRoot' + 'config.urlRoot', + 'config.upstreamProxy' ] this.kill = function (id, callback) { diff --git a/lib/middleware/karma.js b/lib/middleware/karma.js index d59ba8338..1010f04bd 100644 --- a/lib/middleware/karma.js +++ b/lib/middleware/karma.js @@ -35,12 +35,12 @@ var SCRIPT_TYPE = { '.dart': 'application/dart' } -var filePathToUrlPath = function (filePath, basePath, urlRoot) { +var filePathToUrlPath = function (filePath, basePath, urlRoot, proxyPath) { if (filePath.indexOf(basePath) === 0) { - return urlRoot + 'base' + filePath.substr(basePath.length) + return proxyPath + urlRoot.substr(1) + 'base' + filePath.substr(basePath.length) } - return urlRoot + 'absolute' + filePath + return proxyPath + urlRoot.substr(1) + 'absolute' + filePath } var getXUACompatibleMetaElement = function (url) { @@ -79,8 +79,10 @@ var createKarmaMiddleware = function ( serveFile, injector, basePath, - urlRoot + urlRoot, + upstreamProxy ) { + var proxyPath = upstreamProxy ? upstreamProxy.path : '/' return function (request, response, next) { // These config values should be up to date on every request var client = injector.get('config.client') @@ -93,7 +95,7 @@ var createKarmaMiddleware = function ( // redirect /__karma__ to /__karma__ (trailing slash) if (requestUrl === urlRoot.substr(0, urlRoot.length - 1)) { - response.setHeader('Location', urlRoot) + response.setHeader('Location', proxyPath + urlRoot.substr(1)) response.writeHead(301) return response.end('MOVED PERMANENTLY') } @@ -122,6 +124,7 @@ var createKarmaMiddleware = function ( return serveStaticFile(requestUrl, requestedRangeHeader, response, function (data) { return data.replace('%KARMA_URL_ROOT%', urlRoot) .replace('%KARMA_VERSION%', VERSION) + .replace('%KARMA_PROXY_PATH%', proxyPath) }) } @@ -161,7 +164,7 @@ var createKarmaMiddleware = function ( var fileExt = path.extname(filePath) if (!file.isUrl) { - filePath = filePathToUrlPath(filePath, basePath, urlRoot) + filePath = filePathToUrlPath(filePath, basePath, urlRoot, proxyPath) if (requestUrl === '/context.html') { filePath += '?' + file.sha @@ -190,7 +193,7 @@ var createKarmaMiddleware = function ( // TODO(vojta): don't compute if it's not in the template var mappings = files.served.map(function (file) { // Windows paths contain backslashes and generate bad IDs if not escaped - var filePath = filePathToUrlPath(file.path, basePath, urlRoot).replace(/\\/g, '\\\\') + var filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath).replace(/\\/g, '\\\\') // Escape single quotes that might be in the filename - // double quotes should not be allowed! filePath = filePath.replace(/'/g, '\\\'') @@ -223,7 +226,7 @@ var createKarmaMiddleware = function ( response.writeHead(200) response.end(JSON.stringify({ files: files.included.map(function (file) { - return filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot) + return filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath) }) })) }) @@ -239,7 +242,8 @@ createKarmaMiddleware.$inject = [ 'serveFile', 'injector', 'config.basePath', - 'config.urlRoot' + 'config.urlRoot', + 'config.upstreamProxy' ] // PUBLIC API diff --git a/test/e2e/steps/core_steps.js b/test/e2e/steps/core_steps.js index 7b080e6c2..9b4c1fc7a 100644 --- a/test/e2e/steps/core_steps.js +++ b/test/e2e/steps/core_steps.js @@ -71,69 +71,81 @@ module.exports = function coreSteps () { })(this)) }) - this.When(/^I (run|runOut|start|init|stop) Karma( with log-level ([a-z]+))?$/, function (command, withLogLevel, level, callback) { - this.writeConfigFile(tmpDir, tmpConfigFile, (function (_this) { - return function (err, hash) { + this.When(/^I (run|runOut|start|init|stop) Karma( with log-level ([a-z]+))?( behind a proxy on port ([0-9]*) that prepends '([^']*)' to the base path)?$/, function (command, withLogLevel, level, behindProxy, proxyPort, proxyPath, callback) { + var startProxy = function (done) { + if (behindProxy) { + this.proxy.start(proxyPort, proxyPath, done) + } else { + done() + } + } + startProxy.call(this, (function (_this) { + return function (err) { if (err) { - return callback.fail(new Error(err)) + return callback.fail(err) } - level = withLogLevel === undefined ? 'warn' : level - var configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) - var runtimePath = path.join(baseDir, 'bin', 'karma') - var execKarma = function (done) { - var cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs - - return exec(cmd, { - cwd: baseDir - }, done) - } - var runOut = command === 'runOut' - if (command === 'run' || command === 'runOut') { - _this.child = spawn('' + runtimePath, ['start', '--log-level', 'warn', configFile]) - var done = function () { - cleansingNeeded = true - _this.child && _this.child.kill() - callback() + _this.writeConfigFile(tmpDir, tmpConfigFile, function (err, hash) { + if (err) { + return callback.fail(new Error(err)) + } + level = withLogLevel === undefined ? 'warn' : level + var configFile = path.join(tmpDir, hash + '.' + tmpConfigFile) + var runtimePath = path.join(baseDir, 'bin', 'karma') + var execKarma = function (done) { + var cmd = runtimePath + ' ' + command + ' --log-level ' + level + ' ' + configFile + ' ' + additionalArgs + + return exec(cmd, { + cwd: baseDir + }, done) } + var runOut = command === 'runOut' + if (command === 'run' || command === 'runOut') { + _this.child = spawn('' + runtimePath, ['start', '--log-level', 'warn', configFile]) + var done = function () { + cleansingNeeded = true + _this.child && _this.child.kill() + callback() + } - _this.child.on('error', function (error) { - _this.lastRun.error = error - done() - }) - - _this.child.stderr.on('data', function (chunk) { - _this.lastRun.stderr += chunk.toString() - }) - - _this.child.stdout.on('data', function (chunk) { - _this.lastRun.stdout += chunk.toString() - var cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs - - setTimeout(function () { - exec(cmd, { - cwd: baseDir - }, function (error, stdout) { - if (error) { - _this.lastRun.error = error - } - if (runOut) { - _this.lastRun.stdout = stdout - } - done() - }) - }, 1000) - }) - } else { - execKarma(function (error, stdout, stderr) { - if (error) { + _this.child.on('error', function (error) { _this.lastRun.error = error - } - _this.lastRun.stdout = stdout - _this.lastRun.stderr = stderr - cleansingNeeded = true - callback() - }) - } + done() + }) + + _this.child.stderr.on('data', function (chunk) { + _this.lastRun.stderr += chunk.toString() + }) + + _this.child.stdout.on('data', function (chunk) { + _this.lastRun.stdout += chunk.toString() + var cmd = runtimePath + ' run ' + configFile + ' ' + additionalArgs + + setTimeout(function () { + exec(cmd, { + cwd: baseDir + }, function (error, stdout) { + if (error) { + _this.lastRun.error = error + } + if (runOut) { + _this.lastRun.stdout = stdout + } + done() + }) + }, 1000) + }) + } else { + execKarma(function (error, stdout, stderr) { + if (error) { + _this.lastRun.error = error + } + _this.lastRun.stdout = stdout + _this.lastRun.stderr = stderr + cleansingNeeded = true + callback() + }) + } + }) } })(this)) }) diff --git a/test/e2e/support/after_hooks.js b/test/e2e/support/after_hooks.js index 8dc48c76b..155f2cb4e 100644 --- a/test/e2e/support/after_hooks.js +++ b/test/e2e/support/after_hooks.js @@ -1,10 +1,13 @@ module.exports = function afterHooks () { - this.After(function (callback) { + this.After(function (scenario, callback) { var running = this.child != null && typeof this.child.kill === 'function' if (running) { this.child.kill() this.child = null } + + // stop the proxy if it was started + this.proxy.stop(callback) }) } diff --git a/test/e2e/support/behind-proxy/plus.js b/test/e2e/support/behind-proxy/plus.js new file mode 100644 index 000000000..d7fd9e84e --- /dev/null +++ b/test/e2e/support/behind-proxy/plus.js @@ -0,0 +1,5 @@ +/* eslint-disable no-unused-vars */ +// Some code under test +function plus (a, b) { + return a + b +} diff --git a/test/e2e/support/behind-proxy/test.js b/test/e2e/support/behind-proxy/test.js new file mode 100644 index 000000000..e2883be26 --- /dev/null +++ b/test/e2e/support/behind-proxy/test.js @@ -0,0 +1,10 @@ +/* globals plus */ +describe('plus', function () { + it('should pass', function () { + expect(true).toBe(true) + }) + + it('should work', function () { + expect(plus(1, 2)).toBe(3) + }) +}) diff --git a/test/e2e/support/proxy.js b/test/e2e/support/proxy.js new file mode 100644 index 000000000..bd58e3474 --- /dev/null +++ b/test/e2e/support/proxy.js @@ -0,0 +1,43 @@ +var http = require('http') +var httpProxy = require('http-proxy') + +var Proxy = function () { + var self = this + self.running = false + + self.proxy = httpProxy.createProxyServer({ + target: 'http://localhost:9876' + }) + + self.server = http.createServer(function (req, res) { + var url = req.url + var match = url.match(self.proxyPathRegExp) + if (match) { + req.url = '/' + match[1] + self.proxy.web(req, res) + } else { + res.statusCode = 404 + res.statusMessage = 'Not found' + res.end() + } + }) + + self.start = function (port, proxyPath, callback) { + self.proxyPathRegExp = new RegExp('^' + proxyPath + '(.*)') + self.server.listen(port, function (error) { + self.running = !error + callback(error) + }) + } + + self.stop = function (callback) { + if (self.running) { + self.running = false + self.server.close(callback) + } else { + callback() + } + } +} + +module.exports = new Proxy() diff --git a/test/e2e/support/world.js b/test/e2e/support/world.js index fbdb8eb56..7a2d02e3f 100644 --- a/test/e2e/support/world.js +++ b/test/e2e/support/world.js @@ -6,6 +6,8 @@ var mkdirp = require('mkdirp') var _ = require('lodash') exports.World = function World () { + this.proxy = require('./proxy') + this.template = _.template('module.exports = function (config) {\n config.set(\n <%= content %>\n );\n};') this.configFile = { diff --git a/test/e2e/upstream-proxy.feature b/test/e2e/upstream-proxy.feature new file mode 100644 index 000000000..732190cb4 --- /dev/null +++ b/test/e2e/upstream-proxy.feature @@ -0,0 +1,25 @@ +Feature: UpstreamProxy + In order to use Karma + As a person who wants to write great tests + I want to Karma to to work when it is behind a proxy that prepends to the base path. + + Scenario: UpstreamProxy + Given a configuration with: + """ + files = ['behind-proxy/plus.js', 'behind-proxy/test.js']; + browsers = ['PhantomJS']; + plugins = [ + 'karma-jasmine', + 'karma-phantomjs-launcher' + ]; + urlRoot = '/__karma__/'; + upstreamProxy = { + path: '/__proxy__/' + }; + """ + When I start Karma behind a proxy on port 9875 that prepends '/__proxy__/' to the base path + Then it passes with: + """ + .. + PhantomJS + """ diff --git a/test/unit/config.spec.js b/test/unit/config.spec.js index 11294332f..4bcd91497 100644 --- a/test/unit/config.spec.js +++ b/test/unit/config.spec.js @@ -12,6 +12,7 @@ describe('config', () => { var normalizeConfigWithDefaults = (cfg) => { if (!cfg.urlRoot) cfg.urlRoot = '' + if (!cfg.proxyPath) cfg.proxyPath = '' if (!cfg.files) cfg.files = [] if (!cfg.exclude) cfg.exclude = [] if (!cfg.junitReporter) cfg.junitReporter = {} @@ -188,6 +189,35 @@ describe('config', () => { expect(config.urlRoot).to.equal('/some/thing/') }) + it('should normalize upstream proxy config', () => { + var config = normalizeConfigWithDefaults({}) + expect(config.upstreamProxy).to.be.undefined + + config = normalizeConfigWithDefaults({upstreamProxy: {}}) + expect(config.upstreamProxy.path).to.equal('/') + expect(config.upstreamProxy.hostname).to.equal('localhost') + expect(config.upstreamProxy.port).to.equal(9875) + expect(config.upstreamProxy.protocol).to.equal('http:') + + config = normalizeConfigWithDefaults({upstreamProxy: {protocol: 'http'}}) + expect(config.upstreamProxy.protocol).to.equal('http:') + + config = normalizeConfigWithDefaults({upstreamProxy: {protocol: 'https'}}) + expect(config.upstreamProxy.protocol).to.equal('https:') + + config = normalizeConfigWithDefaults({upstreamProxy: {protocol: 'unknown'}}) + expect(config.upstreamProxy.protocol).to.equal('http:') + + config = normalizeConfigWithDefaults({upstreamProxy: {path: '/a/b'}}) + expect(config.upstreamProxy.path).to.equal('/a/b/') + + config = normalizeConfigWithDefaults({upstreamProxy: {path: 'a/'}}) + expect(config.upstreamProxy.path).to.equal('/a/') + + config = normalizeConfigWithDefaults({upstreamProxy: {path: 'some/thing'}}) + expect(config.upstreamProxy.path).to.equal('/some/thing/') + }) + it('should change autoWatch to false if singleRun', () => { // config4.js has autoWatch = true var config = m.parseConfig('/home/config4.js', {singleRun: true}) diff --git a/test/unit/launcher.spec.js b/test/unit/launcher.spec.js index 366fc16ba..81e11031f 100644 --- a/test/unit/launcher.spec.js +++ b/test/unit/launcher.spec.js @@ -123,6 +123,48 @@ describe('launcher', () => { }) }) + describe('with upstream proxy settings', () => { + beforeEach(() => { + emitter = new events.EventEmitter() + server = {'loadErrors': []} + config = { + captureTimeout: 0, + protocol: 'http:', + hostname: 'localhost', + port: 1234, + urlRoot: '/root/', + upstreamProxy: { + path: '/__proxy__/', + hostname: 'proxy', + port: '5678', + protocol: 'https:' + } + } + + var injector = new di.Injector([{ + 'launcher:Fake': ['type', FakeBrowser], + 'launcher:Script': ['type', ScriptBrowser], + 'server': ['value', server], + 'emitter': ['value', emitter], + 'config': ['value', config], + 'timer': ['factory', createMockTimer] + }]) + l = new launcher.Launcher(server, emitter, injector) + }) + + it('should inject and start all browsers', (done) => { + l.launch(['Fake'], 1) + + var browser = FakeBrowser._instances.pop() + l.jobs.on('end', () => { + expect(browser.start).to.have.been.calledWith('https://proxy:5678/__proxy__/root/') + expect(browser.id).to.equal(lastGeneratedId) + expect(browser.name).to.equal('Fake') + done() + }) + }) + }) + it('should not start when server has load errors', (done) => { server.loadErrors = ['error'] l.launch(['Fake'], 1) diff --git a/test/unit/middleware/karma.spec.js b/test/unit/middleware/karma.spec.js index 305e765d6..bb742bf73 100644 --- a/test/unit/middleware/karma.spec.js +++ b/test/unit/middleware/karma.spec.js @@ -24,7 +24,7 @@ describe('middleware.karma', () => { 'client.html': mocks.fs.file(0, 'CLIENT HTML\n%X_UA_COMPATIBLE%%X_UA_COMPATIBLE_URL%'), 'context.html': mocks.fs.file(0, 'CONTEXT\n%SCRIPTS%'), 'debug.html': mocks.fs.file(0, 'DEBUG\n%SCRIPTS%\n%X_UA_COMPATIBLE%'), - 'karma.js': mocks.fs.file(0, 'root: %KARMA_URL_ROOT%, v: %KARMA_VERSION%') + 'karma.js': mocks.fs.file(0, 'root: %KARMA_URL_ROOT%, proxy: %KARMA_PROXY_PATH%, v: %KARMA_VERSION%') } } }) @@ -57,7 +57,8 @@ describe('middleware.karma', () => { null, injector, '/base/path', - '/__karma__/' + '/__karma__/', + {path: '/__proxy__/'} ) }) @@ -85,7 +86,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called expect(response).to.beServedAs(301, 'MOVED PERMANENTLY') - expect(response._headers['Location']).to.equal('/__karma__/') + expect(response._headers['Location']).to.equal('/__proxy__/__karma__/') done() }) @@ -181,7 +182,7 @@ describe('middleware.karma', () => { it('should serve karma.js with version and urlRoot variables', (done) => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'root: /__karma__/, v: ' + constants.VERSION) + expect(response).to.beServedAs(200, 'root: /__karma__/, proxy: /__proxy__/, v: ' + constants.VERSION) expect(response._headers['Content-Type']).to.equal('application/javascript') done() }) @@ -197,7 +198,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'CONTEXT\n\n') + expect(response).to.beServedAs(200, 'CONTEXT\n\n') done() }) @@ -212,7 +213,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'CONTEXT\n\n') + expect(response).to.beServedAs(200, 'CONTEXT\n\n') done() }) @@ -227,7 +228,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'CONTEXT\n\n') + expect(response).to.beServedAs(200, 'CONTEXT\n\n') done() }) @@ -244,7 +245,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'CONTEXT\n\n\n\n') + expect(response).to.beServedAs(200, 'CONTEXT\n\n\n\n') done() }) @@ -263,10 +264,10 @@ describe('middleware.karma', () => { expect(nextSpy).not.to.have.been.called expect(response).to.beServedAs(200, JSON.stringify({ files: [ - '/__karma__/absolute/some/abc/a.css?sha1', - '/__karma__/base/b.css?sha2', - '/__karma__/absolute/some/abc/c.html?sha3', - '/__karma__/base/d.html?sha4' + '/__proxy__/__karma__/absolute/some/abc/a.css?sha1', + '/__proxy__/__karma__/base/b.css?sha2', + '/__proxy__/__karma__/absolute/some/abc/c.html?sha3', + '/__proxy__/__karma__/base/d.html?sha4' ] })) done() @@ -314,7 +315,7 @@ describe('middleware.karma', () => { ]) response.once('end', () => { - expect(response).to.beServedAs(200, "window.__karma__.files = {\n '/__karma__/absolute/some/abc/a.js': 'sha_a',\n '/__karma__/base/b.js': 'sha_b',\n '/__karma__/absolute\\\\windows\\\\path\\\\uuu\\\\c.js': 'sha_c'\n};\n") + expect(response).to.beServedAs(200, "window.__karma__.files = {\n '/__proxy__/__karma__/absolute/some/abc/a.js': 'sha_a',\n '/__proxy__/__karma__/base/b.js': 'sha_b',\n '/__proxy__/__karma__/absolute\\\\windows\\\\path\\\\uuu\\\\c.js': 'sha_c'\n};\n") done() }) @@ -329,7 +330,7 @@ describe('middleware.karma', () => { ]) response.once('end', () => { - expect(response).to.beServedAs(200, 'window.__karma__.files = {\n \'/__karma__/absolute/some/abc/a\\\'b.js\': \'sha_a\',\n \'/__karma__/base/ba.js\': \'sha_b\'\n};\n') + expect(response).to.beServedAs(200, 'window.__karma__.files = {\n \'/__proxy__/__karma__/absolute/some/abc/a\\\'b.js\': \'sha_a\',\n \'/__proxy__/__karma__/base/ba.js\': \'sha_b\'\n};\n') done() }) @@ -344,7 +345,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'DEBUG\n\n') + expect(response).to.beServedAs(200, 'DEBUG\n\n') done() }) @@ -361,7 +362,7 @@ describe('middleware.karma', () => { response.once('end', () => { expect(nextSpy).not.to.have.been.called - expect(response).to.beServedAs(200, 'DEBUG\n\n\n\n') + expect(response).to.beServedAs(200, 'DEBUG\n\n\n\n') done() }) @@ -412,7 +413,8 @@ describe('middleware.karma', () => { } }, '/base/path', - '/__karma__/' + '/__karma__/', + {path: '/__proxy__/'} ) includedFiles([