Updated the files.
This commit is contained in:
parent
1553e6b971
commit
753967d4f5
23418 changed files with 3784666 additions and 0 deletions
105
my-app/node_modules/karma/lib/middleware/common.js
generated
vendored
Executable file
105
my-app/node_modules/karma/lib/middleware/common.js
generated
vendored
Executable file
|
@ -0,0 +1,105 @@
|
|||
/**
|
||||
* This module contains some common helpers shared between middlewares
|
||||
*/
|
||||
'use strict'
|
||||
|
||||
const mime = require('mime')
|
||||
const parseRange = require('range-parser')
|
||||
const log = require('../logger').create('web-server')
|
||||
|
||||
function createServeFile (fs, directory, config) {
|
||||
const cache = Object.create(null)
|
||||
|
||||
return function (filepath, rangeHeader, response, transform, content, doNotCache) {
|
||||
let responseData
|
||||
|
||||
function convertForRangeRequest () {
|
||||
const range = parseRange(responseData.length, rangeHeader)
|
||||
if (range === -2) {
|
||||
return 200 // malformed header string
|
||||
} else if (range === -1) {
|
||||
responseData = Buffer.alloc(0) // unsatisfiable range
|
||||
return 416
|
||||
} else if (range.type === 'bytes') {
|
||||
responseData = Buffer.from(responseData)
|
||||
if (range.length === 1) {
|
||||
const { start, end } = range[0]
|
||||
response.setHeader('Content-Range', `bytes ${start}-${end}/${responseData.length}`)
|
||||
response.setHeader('Accept-Ranges', 'bytes')
|
||||
response.setHeader('Content-Length', end - start + 1)
|
||||
responseData = responseData.slice(start, end + 1)
|
||||
return 206
|
||||
} else {
|
||||
responseData = Buffer.alloc(0) // Multiple ranges are not supported. Maybe future?
|
||||
return 416
|
||||
}
|
||||
}
|
||||
return 200 // All other states, ignore
|
||||
}
|
||||
|
||||
if (directory) {
|
||||
filepath = directory + filepath
|
||||
}
|
||||
|
||||
if (!content && cache[filepath]) {
|
||||
content = cache[filepath]
|
||||
}
|
||||
|
||||
if (config && config.customHeaders && config.customHeaders.length > 0) {
|
||||
config.customHeaders.forEach((header) => {
|
||||
const regex = new RegExp(header.match)
|
||||
if (regex.test(filepath)) {
|
||||
log.debug(`setting header: ${header.name} for: ${filepath}`)
|
||||
response.setHeader(header.name, header.value)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
if (content && !doNotCache) {
|
||||
log.debug(`serving (cached): ${filepath}`)
|
||||
response.setHeader('Content-Type', mime.getType(filepath, 'text/plain'))
|
||||
responseData = (transform && transform(content)) || content
|
||||
response.writeHead(rangeHeader ? convertForRangeRequest() : 200)
|
||||
return response.end(responseData)
|
||||
}
|
||||
|
||||
return fs.readFile(filepath, function (error, data) {
|
||||
if (error) {
|
||||
return serve404(response, filepath)
|
||||
}
|
||||
|
||||
if (!doNotCache) {
|
||||
cache[filepath] = data.toString()
|
||||
}
|
||||
|
||||
log.debug('serving: ' + filepath)
|
||||
response.setHeader('Content-Type', mime.getType(filepath, 'text/plain'))
|
||||
responseData = (transform && transform(data.toString())) || data
|
||||
response.writeHead(rangeHeader ? convertForRangeRequest() : 200)
|
||||
|
||||
return response.end(responseData)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
function serve404 (response, path) {
|
||||
log.warn(`404: ${path}`)
|
||||
response.writeHead(404)
|
||||
return response.end('NOT FOUND')
|
||||
}
|
||||
|
||||
function setNoCacheHeaders (response) {
|
||||
response.setHeader('Cache-Control', 'no-cache')
|
||||
response.setHeader('Pragma', 'no-cache')
|
||||
response.setHeader('Expires', (new Date(0)).toUTCString())
|
||||
}
|
||||
|
||||
function setHeavyCacheHeaders (response) {
|
||||
response.setHeader('Cache-Control', 'public, max-age=31536000')
|
||||
}
|
||||
|
||||
// PUBLIC API
|
||||
exports.createServeFile = createServeFile
|
||||
exports.setNoCacheHeaders = setNoCacheHeaders
|
||||
exports.setHeavyCacheHeaders = setHeavyCacheHeaders
|
||||
exports.serve404 = serve404
|
259
my-app/node_modules/karma/lib/middleware/karma.js
generated
vendored
Executable file
259
my-app/node_modules/karma/lib/middleware/karma.js
generated
vendored
Executable file
|
@ -0,0 +1,259 @@
|
|||
/**
|
||||
* Karma middleware is responsible for serving:
|
||||
* - client.html (the entrypoint for capturing a browser)
|
||||
* - debug.html
|
||||
* - context.html (the execution context, loaded within an iframe)
|
||||
* - karma.js
|
||||
*
|
||||
* The main part is generating context.html, as it contains:
|
||||
* - generating mappings
|
||||
* - including <script> and <link> tags
|
||||
* - setting propert caching headers
|
||||
*/
|
||||
|
||||
const url = require('url')
|
||||
|
||||
const log = require('../logger').create('middleware:karma')
|
||||
const stripHost = require('./strip_host').stripHost
|
||||
const common = require('./common')
|
||||
|
||||
const VERSION = require('../constants').VERSION
|
||||
const SCRIPT_TYPE = {
|
||||
js: 'text/javascript',
|
||||
module: 'module'
|
||||
}
|
||||
const FILE_TYPES = [
|
||||
'css',
|
||||
'html',
|
||||
'js',
|
||||
'module',
|
||||
'dom'
|
||||
]
|
||||
|
||||
function filePathToUrlPath (filePath, basePath, urlRoot, proxyPath) {
|
||||
if (filePath.startsWith(basePath)) {
|
||||
return proxyPath + urlRoot.slice(1) + 'base' + filePath.slice(basePath.length)
|
||||
}
|
||||
return proxyPath + urlRoot.slice(1) + 'absolute' + filePath
|
||||
}
|
||||
|
||||
function getQuery (urlStr) {
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
return url.parse(urlStr, true).query || {}
|
||||
}
|
||||
|
||||
function getXUACompatibleMetaElement (url) {
|
||||
const query = getQuery(url)
|
||||
if (query['x-ua-compatible']) {
|
||||
return `<meta http-equiv="X-UA-Compatible" content="${query['x-ua-compatible']}"/>`
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function getXUACompatibleUrl (url) {
|
||||
const query = getQuery(url)
|
||||
if (query['x-ua-compatible']) {
|
||||
return '?x-ua-compatible=' + encodeURIComponent(query['x-ua-compatible'])
|
||||
}
|
||||
return ''
|
||||
}
|
||||
|
||||
function createKarmaMiddleware (
|
||||
filesPromise,
|
||||
serveStaticFile,
|
||||
serveFile,
|
||||
injector,
|
||||
basePath,
|
||||
urlRoot,
|
||||
upstreamProxy,
|
||||
browserSocketTimeout
|
||||
) {
|
||||
const proxyPath = upstreamProxy ? upstreamProxy.path : '/'
|
||||
return function (request, response, next) {
|
||||
// These config values should be up to date on every request
|
||||
const client = injector.get('config.client')
|
||||
const customContextFile = injector.get('config.customContextFile')
|
||||
const customDebugFile = injector.get('config.customDebugFile')
|
||||
const customClientContextFile = injector.get('config.customClientContextFile')
|
||||
const includeCrossOriginAttribute = injector.get('config.crossOriginAttribute')
|
||||
|
||||
const normalizedUrl = stripHost(request.url) || request.url
|
||||
// For backwards compatibility in middleware plugins, remove in v4.
|
||||
request.normalizedUrl = normalizedUrl
|
||||
|
||||
let requestUrl = normalizedUrl.replace(/\?.*/, '')
|
||||
const requestedRangeHeader = request.headers.range
|
||||
|
||||
// redirect /__karma__ to /__karma__ (trailing slash)
|
||||
if (requestUrl === urlRoot.slice(0, -1)) {
|
||||
response.setHeader('Location', proxyPath + urlRoot.slice(1))
|
||||
response.writeHead(301)
|
||||
return response.end('MOVED PERMANENTLY')
|
||||
}
|
||||
|
||||
// ignore urls outside urlRoot
|
||||
if (!requestUrl.startsWith(urlRoot)) {
|
||||
return next()
|
||||
}
|
||||
|
||||
// remove urlRoot prefix
|
||||
requestUrl = requestUrl.slice(urlRoot.length - 1)
|
||||
|
||||
// serve client.html
|
||||
if (requestUrl === '/') {
|
||||
// redirect client_with_context.html
|
||||
if (!client.useIframe && client.runInParent) {
|
||||
requestUrl = '/client_with_context.html'
|
||||
} else { // serve client.html
|
||||
return serveStaticFile('/client.html', requestedRangeHeader, response, (data) =>
|
||||
data
|
||||
.replace('%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
|
||||
.replace('%X_UA_COMPATIBLE_URL%', getXUACompatibleUrl(request.url)))
|
||||
}
|
||||
}
|
||||
|
||||
if (['/karma.js', '/context.js', '/debug.js'].includes(requestUrl)) {
|
||||
return serveStaticFile(requestUrl, requestedRangeHeader, response, (data) =>
|
||||
data
|
||||
.replace('%KARMA_URL_ROOT%', urlRoot)
|
||||
.replace('%KARMA_VERSION%', VERSION)
|
||||
.replace('%KARMA_PROXY_PATH%', proxyPath)
|
||||
.replace('%BROWSER_SOCKET_TIMEOUT%', browserSocketTimeout))
|
||||
}
|
||||
|
||||
// serve the favicon
|
||||
if (requestUrl === '/favicon.ico') {
|
||||
return serveStaticFile(requestUrl, requestedRangeHeader, response)
|
||||
}
|
||||
|
||||
// serve context.html - execution context within the iframe
|
||||
// or debug.html - execution context without channel to the server
|
||||
const isRequestingContextFile = requestUrl === '/context.html'
|
||||
const isRequestingDebugFile = requestUrl === '/debug.html'
|
||||
const isRequestingClientContextFile = requestUrl === '/client_with_context.html'
|
||||
if (isRequestingContextFile || isRequestingDebugFile || isRequestingClientContextFile) {
|
||||
return filesPromise.then((files) => {
|
||||
let fileServer
|
||||
let requestedFileUrl
|
||||
log.debug('custom files', customContextFile, customDebugFile, customClientContextFile)
|
||||
if (isRequestingContextFile && customContextFile) {
|
||||
log.debug(`Serving customContextFile ${customContextFile}`)
|
||||
fileServer = serveFile
|
||||
requestedFileUrl = customContextFile
|
||||
} else if (isRequestingDebugFile && customDebugFile) {
|
||||
log.debug(`Serving customDebugFile ${customDebugFile}`)
|
||||
fileServer = serveFile
|
||||
requestedFileUrl = customDebugFile
|
||||
} else if (isRequestingClientContextFile && customClientContextFile) {
|
||||
log.debug(`Serving customClientContextFile ${customClientContextFile}`)
|
||||
fileServer = serveFile
|
||||
requestedFileUrl = customClientContextFile
|
||||
} else {
|
||||
log.debug(`Serving static request ${requestUrl}`)
|
||||
fileServer = serveStaticFile
|
||||
requestedFileUrl = requestUrl
|
||||
}
|
||||
|
||||
fileServer(requestedFileUrl, requestedRangeHeader, response, function (data) {
|
||||
common.setNoCacheHeaders(response)
|
||||
|
||||
const scriptTags = []
|
||||
for (const file of files.included) {
|
||||
let filePath = file.path
|
||||
const fileType = file.type || file.detectType()
|
||||
|
||||
if (!FILE_TYPES.includes(fileType)) {
|
||||
if (file.type == null) {
|
||||
log.warn(
|
||||
'Unable to determine file type from the file extension, defaulting to js.\n' +
|
||||
` To silence the warning specify a valid type for ${file.originalPath} in the configuration file.\n` +
|
||||
' See https://karma-runner.github.io/latest/config/files.html'
|
||||
)
|
||||
} else {
|
||||
log.warn(`Invalid file type (${file.type || 'empty string'}), defaulting to js.`)
|
||||
}
|
||||
}
|
||||
|
||||
if (!file.isUrl) {
|
||||
filePath = filePathToUrlPath(filePath, basePath, urlRoot, proxyPath)
|
||||
|
||||
if (requestUrl === '/context.html') {
|
||||
filePath += '?' + file.sha
|
||||
}
|
||||
}
|
||||
|
||||
const integrityAttribute = file.integrity ? ` integrity="${file.integrity}"` : ''
|
||||
const crossOriginAttribute = includeCrossOriginAttribute ? ' crossorigin="anonymous"' : ''
|
||||
if (fileType === 'css') {
|
||||
scriptTags.push(`<link type="text/css" href="${filePath}" rel="stylesheet"${integrityAttribute}${crossOriginAttribute}>`)
|
||||
} else if (fileType === 'dom') {
|
||||
scriptTags.push(file.content)
|
||||
} else if (fileType === 'html') {
|
||||
scriptTags.push(`<link href="${filePath}" rel="import"${integrityAttribute}${crossOriginAttribute}>`)
|
||||
} else {
|
||||
const scriptType = (SCRIPT_TYPE[fileType] || 'text/javascript')
|
||||
if (fileType === 'module') {
|
||||
scriptTags.push(`<script onerror="throw 'Error loading ${filePath}'" type="${scriptType}" src="${filePath}"${integrityAttribute}${crossOriginAttribute}></script>`)
|
||||
} else {
|
||||
scriptTags.push(`<script type="${scriptType}" src="${filePath}"${integrityAttribute}${crossOriginAttribute}></script>`)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const scriptUrls = []
|
||||
// For client_with_context, html elements are not added directly through an iframe.
|
||||
// Instead, scriptTags is stored to window.__karma__.scriptUrls first. Later, the
|
||||
// client will read window.__karma__.scriptUrls and dynamically add them to the DOM
|
||||
// using DOMParser.
|
||||
if (requestUrl === '/client_with_context.html') {
|
||||
for (const script of scriptTags) {
|
||||
scriptUrls.push(
|
||||
// Escape characters with special roles (tags) in HTML. Open angle brackets are parsed as tags
|
||||
// immediately, even if it is within double quotations in browsers
|
||||
script.replace(/</g, '\\x3C').replace(/>/g, '\\x3E'))
|
||||
}
|
||||
}
|
||||
|
||||
const mappings = data.includes('%MAPPINGS%') ? files.served.map((file) => {
|
||||
const filePath = filePathToUrlPath(file.path, basePath, urlRoot, proxyPath)
|
||||
.replace(/\\/g, '\\\\') // Windows paths contain backslashes and generate bad IDs if not escaped
|
||||
.replace(/'/g, '\\\'') // Escape single quotes - double quotes should not be allowed!
|
||||
|
||||
return ` '${filePath}': '${file.sha}'`
|
||||
}) : []
|
||||
|
||||
return data
|
||||
.replace('%SCRIPTS%', () => scriptTags.join('\n'))
|
||||
.replace('%CLIENT_CONFIG%', 'window.__karma__.config = ' + JSON.stringify(client) + ';\n')
|
||||
.replace('%SCRIPT_URL_ARRAY%', () => 'window.__karma__.scriptUrls = ' + JSON.stringify(scriptUrls) + ';\n')
|
||||
.replace('%MAPPINGS%', () => 'window.__karma__.files = {\n' + mappings.join(',\n') + '\n};\n')
|
||||
.replace('%X_UA_COMPATIBLE%', getXUACompatibleMetaElement(request.url))
|
||||
})
|
||||
})
|
||||
} else if (requestUrl === '/context.json') {
|
||||
return filesPromise.then((files) => {
|
||||
common.setNoCacheHeaders(response)
|
||||
response.writeHead(200)
|
||||
response.end(JSON.stringify({
|
||||
files: files.included.map((file) => filePathToUrlPath(file.path + '?' + file.sha, basePath, urlRoot, proxyPath))
|
||||
}))
|
||||
})
|
||||
}
|
||||
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|
||||
createKarmaMiddleware.$inject = [
|
||||
'filesPromise',
|
||||
'serveStaticFile',
|
||||
'serveFile',
|
||||
'injector',
|
||||
'config.basePath',
|
||||
'config.urlRoot',
|
||||
'config.upstreamProxy',
|
||||
'config.browserSocketTimeout'
|
||||
]
|
||||
|
||||
// PUBLIC API
|
||||
exports.create = createKarmaMiddleware
|
130
my-app/node_modules/karma/lib/middleware/proxy.js
generated
vendored
Executable file
130
my-app/node_modules/karma/lib/middleware/proxy.js
generated
vendored
Executable file
|
@ -0,0 +1,130 @@
|
|||
const url = require('url')
|
||||
const { Agent: httpAgent } = require('http')
|
||||
const { Agent: httpsAgent } = require('https')
|
||||
const httpProxy = require('http-proxy')
|
||||
const _ = require('lodash')
|
||||
const { lookup } = require('../utils/dns-utils')
|
||||
|
||||
const log = require('../logger').create('proxy')
|
||||
|
||||
function parseProxyConfig (proxies, config) {
|
||||
proxies = proxies || []
|
||||
return _.sortBy(_.map(proxies, function (proxyConfiguration, proxyPath) {
|
||||
if (typeof proxyConfiguration === 'string') {
|
||||
proxyConfiguration = { target: proxyConfiguration }
|
||||
}
|
||||
let proxyUrl = proxyConfiguration.target
|
||||
// eslint-disable-next-line node/no-deprecated-api
|
||||
const proxyDetails = url.parse(proxyUrl)
|
||||
let pathname = proxyDetails.pathname
|
||||
|
||||
if (proxyPath.endsWith('/') && !proxyUrl.endsWith('/')) {
|
||||
log.warn(`proxy "${proxyUrl}" normalized to "${proxyUrl}/"`)
|
||||
proxyUrl += '/'
|
||||
pathname += '/'
|
||||
}
|
||||
|
||||
if (!proxyPath.endsWith('/') && proxyUrl.endsWith('/')) {
|
||||
log.warn(`proxy "${proxyPath}" normalized to "${proxyPath}/"`)
|
||||
proxyPath += '/'
|
||||
}
|
||||
|
||||
if (pathname === '/' && !proxyUrl.endsWith('/')) {
|
||||
pathname = ''
|
||||
}
|
||||
|
||||
const hostname = proxyDetails.hostname || config.hostname
|
||||
const protocol = proxyDetails.protocol || config.protocol
|
||||
const defaultPorts = {
|
||||
'http:': '80',
|
||||
'https:': '443'
|
||||
}
|
||||
const port = proxyDetails.port || defaultPorts[proxyDetails.protocol] || config.port
|
||||
const changeOrigin = proxyConfiguration.changeOrigin || false
|
||||
const Agent = protocol === 'https:' ? httpsAgent : httpAgent
|
||||
const agent = new Agent({
|
||||
keepAlive: true,
|
||||
lookup
|
||||
})
|
||||
const proxy = httpProxy.createProxyServer({
|
||||
target: { host: hostname, port, protocol },
|
||||
xfwd: true,
|
||||
changeOrigin: changeOrigin,
|
||||
secure: config.proxyValidateSSL,
|
||||
agent
|
||||
})
|
||||
|
||||
;['proxyReq', 'proxyRes'].forEach(function (name) {
|
||||
const callback = proxyDetails[name] || config[name]
|
||||
if (callback) {
|
||||
proxy.on(name, callback)
|
||||
}
|
||||
})
|
||||
|
||||
proxy.on('error', function proxyError (err, req, res) {
|
||||
if (err.code === 'ECONNRESET' && req.socket.destroyed) {
|
||||
log.debug(`failed to proxy ${req.url} (browser hung up the socket)`)
|
||||
} else {
|
||||
log.warn(`failed to proxy ${req.url} (${err.message})`)
|
||||
}
|
||||
|
||||
res.destroy()
|
||||
})
|
||||
|
||||
return { path: proxyPath, baseUrl: pathname, host: hostname, port, proxy, agent }
|
||||
}), 'path').reverse()
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a handler which understands the proxies and its redirects, along with the proxy to use
|
||||
* @param proxies An array of proxy record objects
|
||||
* @param urlRoot The URL root that karma is mounted on
|
||||
* @return {Function} handler function
|
||||
*/
|
||||
function createProxyHandler (proxies, urlRoot) {
|
||||
if (!proxies.length) {
|
||||
const nullProxy = (request, response, next) => next()
|
||||
nullProxy.upgrade = () => {}
|
||||
return nullProxy
|
||||
}
|
||||
|
||||
function createProxy (request, response, next) {
|
||||
const proxyRecord = proxies.find((p) => request.url.startsWith(p.path))
|
||||
if (proxyRecord) {
|
||||
log.debug(`proxying request - ${request.url} to ${proxyRecord.host}:${proxyRecord.port}`)
|
||||
request.url = request.url.replace(proxyRecord.path, proxyRecord.baseUrl)
|
||||
proxyRecord.proxy.web(request, response)
|
||||
} else {
|
||||
return next()
|
||||
}
|
||||
}
|
||||
|
||||
createProxy.upgrade = function (request, socket, head) {
|
||||
// special-case karma's route to avoid upgrading it
|
||||
if (request.url.startsWith(urlRoot)) {
|
||||
log.debug(`NOT upgrading proxyWebSocketRequest ${request.url}`)
|
||||
return
|
||||
}
|
||||
|
||||
const proxyRecord = proxies.find((p) => request.url.startsWith(p.path))
|
||||
if (proxyRecord) {
|
||||
log.debug(`upgrade proxyWebSocketRequest ${request.url} to ${proxyRecord.host}:${proxyRecord.port}`)
|
||||
request.url = request.url.replace(proxyRecord.path, proxyRecord.baseUrl)
|
||||
proxyRecord.proxy.ws(request, socket, head)
|
||||
}
|
||||
}
|
||||
|
||||
return createProxy
|
||||
}
|
||||
|
||||
exports.create = function (/* config */config, /* config.proxies */proxies, /* emitter */emitter) {
|
||||
const proxyRecords = parseProxyConfig(proxies, config)
|
||||
emitter.on('exit', (done) => {
|
||||
log.debug('Destroying proxy agents')
|
||||
proxyRecords.forEach((proxyRecord) => {
|
||||
proxyRecord.agent.destroy()
|
||||
})
|
||||
done()
|
||||
})
|
||||
return createProxyHandler(proxyRecords, config.urlRoot)
|
||||
}
|
114
my-app/node_modules/karma/lib/middleware/runner.js
generated
vendored
Executable file
114
my-app/node_modules/karma/lib/middleware/runner.js
generated
vendored
Executable file
|
@ -0,0 +1,114 @@
|
|||
/**
|
||||
* Runner middleware is responsible for communication with `karma run`.
|
||||
*
|
||||
* It basically triggers a test run and streams stdout back.
|
||||
*/
|
||||
|
||||
const _ = require('lodash')
|
||||
const path = require('path')
|
||||
const helper = require('../helper')
|
||||
const log = require('../logger').create()
|
||||
const constant = require('../constants')
|
||||
const json = require('body-parser').json()
|
||||
|
||||
// TODO(vojta): disable when single-run mode
|
||||
function createRunnerMiddleware (emitter, fileList, capturedBrowsers, reporter, executor,
|
||||
/* config.protocol */ protocol, /* config.hostname */ hostname, /* config.port */
|
||||
port, /* config.urlRoot */ urlRoot, config) {
|
||||
helper.saveOriginalArgs(config)
|
||||
return function (request, response, next) {
|
||||
if (request.url !== '/__run__' && request.url !== urlRoot + 'run') {
|
||||
return next()
|
||||
}
|
||||
|
||||
log.debug('Execution (fired by runner)')
|
||||
response.writeHead(200)
|
||||
|
||||
if (!capturedBrowsers.length) {
|
||||
const url = `${protocol}//${hostname}:${port}${urlRoot}`
|
||||
return response.end(`No captured browser, open ${url}\n`)
|
||||
}
|
||||
|
||||
json(request, response, function () {
|
||||
if (!capturedBrowsers.areAllReady([])) {
|
||||
response.write('Waiting for previous execution...\n')
|
||||
}
|
||||
|
||||
const data = request.body
|
||||
|
||||
updateClientArgs(data)
|
||||
handleRun(data)
|
||||
refreshFileList(data).then(() => {
|
||||
executor.schedule()
|
||||
}).catch((error) => {
|
||||
const errorMessage = `Error during refresh file list. ${error.stack || error}`
|
||||
executor.scheduleError(errorMessage)
|
||||
})
|
||||
})
|
||||
|
||||
function updateClientArgs (data) {
|
||||
helper.restoreOriginalArgs(config)
|
||||
if (_.isEmpty(data.args)) {
|
||||
log.debug('Ignoring empty client.args from run command')
|
||||
} else if ((_.isArray(data.args) && _.isArray(config.client.args)) ||
|
||||
(_.isPlainObject(data.args) && _.isPlainObject(config.client.args))) {
|
||||
log.debug('Merging client.args with ', data.args)
|
||||
config.client.args = _.merge(config.client.args, data.args)
|
||||
} else {
|
||||
log.warn('Replacing client.args with ', data.args, ' as their types do not match.')
|
||||
config.client.args = data.args
|
||||
}
|
||||
}
|
||||
|
||||
async function refreshFileList (data) {
|
||||
let fullRefresh = true
|
||||
|
||||
if (helper.isArray(data.changedFiles)) {
|
||||
await Promise.all(data.changedFiles.map(async function (filepath) {
|
||||
await fileList.changeFile(path.resolve(config.basePath, filepath))
|
||||
fullRefresh = false
|
||||
}))
|
||||
}
|
||||
|
||||
if (helper.isArray(data.addedFiles)) {
|
||||
await Promise.all(data.addedFiles.map(async function (filepath) {
|
||||
await fileList.addFile(path.resolve(config.basePath, filepath))
|
||||
fullRefresh = false
|
||||
}))
|
||||
}
|
||||
|
||||
if (helper.isArray(data.removedFiles)) {
|
||||
await Promise.all(data.removedFiles.map(async function (filepath) {
|
||||
await fileList.removeFile(path.resolve(config.basePath, filepath))
|
||||
fullRefresh = false
|
||||
}))
|
||||
}
|
||||
|
||||
if (fullRefresh && data.refresh !== false) {
|
||||
log.debug('Refreshing all the files / patterns')
|
||||
await fileList.refresh()
|
||||
}
|
||||
}
|
||||
|
||||
function handleRun (data) {
|
||||
emitter.once('run_start', function () {
|
||||
const responseWrite = response.write.bind(response)
|
||||
responseWrite.colors = data.colors
|
||||
reporter.addAdapter(responseWrite)
|
||||
|
||||
// clean up, close runner response
|
||||
emitter.once('run_complete', function (_browsers, results) {
|
||||
reporter.removeAdapter(responseWrite)
|
||||
const emptyTestSuite = (results.failed + results.success) === 0 ? 0 : 1
|
||||
response.end(constant.EXIT_CODE + emptyTestSuite + results.exitCode)
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
createRunnerMiddleware.$inject = ['emitter', 'fileList', 'capturedBrowsers', 'reporter', 'executor',
|
||||
'config.protocol', 'config.hostname', 'config.port', 'config.urlRoot', 'config']
|
||||
|
||||
// PUBLIC API
|
||||
exports.create = createRunnerMiddleware
|
67
my-app/node_modules/karma/lib/middleware/source_files.js
generated
vendored
Executable file
67
my-app/node_modules/karma/lib/middleware/source_files.js
generated
vendored
Executable file
|
@ -0,0 +1,67 @@
|
|||
'use strict'
|
||||
|
||||
const querystring = require('querystring')
|
||||
const common = require('./common')
|
||||
|
||||
const log = require('../logger').create('middleware:source-files')
|
||||
|
||||
function findByPath (files, path) {
|
||||
return Array.from(files).find((file) => file.path === path)
|
||||
}
|
||||
|
||||
function composeUrl (url, basePath, urlRoot) {
|
||||
return url
|
||||
.replace(urlRoot, '/')
|
||||
.replace(/\?.*$/, '')
|
||||
.replace(/^\/absolute/, '')
|
||||
.replace(/^\/base/, basePath)
|
||||
}
|
||||
|
||||
// Source Files middleware is responsible for serving all the source files under the test.
|
||||
function createSourceFilesMiddleware (filesPromise, serveFile, basePath, urlRoot) {
|
||||
return function (request, response, next) {
|
||||
const requestedFilePath = composeUrl(request.url, basePath, urlRoot)
|
||||
// When a path contains HTML-encoded characters (e.g %2F used by Jenkins for branches with /)
|
||||
const requestedFilePathUnescaped = composeUrl(querystring.unescape(request.url), basePath, urlRoot)
|
||||
|
||||
request.pause()
|
||||
|
||||
log.debug(`Requesting ${request.url}`)
|
||||
log.debug(`Fetching ${requestedFilePath}`)
|
||||
|
||||
return filesPromise.then(function (files) {
|
||||
// TODO(vojta): change served to be a map rather then an array
|
||||
const file = findByPath(files.served, requestedFilePath) || findByPath(files.served, requestedFilePathUnescaped)
|
||||
const rangeHeader = request.headers.range
|
||||
|
||||
if (file) {
|
||||
const acceptEncodingHeader = request.headers['accept-encoding']
|
||||
const matchedEncoding = Object.keys(file.encodings).find(
|
||||
(encoding) => new RegExp(`(^|.*, ?)${encoding}(,|$)`).test(acceptEncodingHeader)
|
||||
)
|
||||
const content = file.encodings[matchedEncoding] || file.content
|
||||
|
||||
serveFile(file.contentPath || file.path, rangeHeader, response, function () {
|
||||
if (/\?\w+/.test(request.url)) {
|
||||
common.setHeavyCacheHeaders(response) // files with timestamps - cache one year, rely on timestamps
|
||||
} else {
|
||||
common.setNoCacheHeaders(response) // without timestamps - no cache (debug)
|
||||
}
|
||||
if (matchedEncoding) {
|
||||
response.setHeader('Content-Encoding', matchedEncoding)
|
||||
}
|
||||
}, content, file.doNotCache)
|
||||
} else {
|
||||
next()
|
||||
}
|
||||
|
||||
request.resume()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
createSourceFilesMiddleware.$inject = [
|
||||
'filesPromise', 'serveFile', 'config.basePath', 'config.urlRoot'
|
||||
]
|
||||
|
||||
exports.create = createSourceFilesMiddleware
|
18
my-app/node_modules/karma/lib/middleware/stopper.js
generated
vendored
Executable file
18
my-app/node_modules/karma/lib/middleware/stopper.js
generated
vendored
Executable file
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Stopper middleware is responsible for communicating with `karma stop`.
|
||||
*/
|
||||
|
||||
const log = require('../logger').create('middleware:stopper')
|
||||
|
||||
function createStopperMiddleware (urlRoot) {
|
||||
return function (request, response, next) {
|
||||
if (request.url !== urlRoot + 'stop') return next()
|
||||
response.writeHead(200)
|
||||
log.info('Stopping server')
|
||||
response.end('OK')
|
||||
process.kill(process.pid, 'SIGINT')
|
||||
}
|
||||
}
|
||||
|
||||
createStopperMiddleware.$inject = ['config.urlRoot']
|
||||
exports.create = createStopperMiddleware
|
11
my-app/node_modules/karma/lib/middleware/strip_host.js
generated
vendored
Executable file
11
my-app/node_modules/karma/lib/middleware/strip_host.js
generated
vendored
Executable file
|
@ -0,0 +1,11 @@
|
|||
/**
|
||||
* Strip hostname from request path
|
||||
* This to handle requests that uses (normally over proxies) an absoluteURI as request path
|
||||
*/
|
||||
|
||||
function stripHostFromUrl (url) {
|
||||
return url.replace(/^https?:\/\/[a-z.:\d-]+\//, '/')
|
||||
}
|
||||
|
||||
// PUBLIC API
|
||||
exports.stripHost = stripHostFromUrl
|
Loading…
Add table
Add a link
Reference in a new issue