lib/tasks/server/middleware/tests-server/index.js
'use strict';
const cleanBaseURL = require('clean-base-url');
const path = require('path');
const fs = require('fs');
const logger = require('heimdalljs-logger')('ember-cli:test-server');
module.exports = class TestsServerAddon {
/**
* This addon is used to serve the QUnit or Mocha test runner
* at `rootURL + '/tests'`.
*
* @class TestsServerAddon
* @constructor
*/
constructor(project) {
this.project = project;
this.name = 'tests-server-middleware';
}
serverMiddleware(config) {
let app = config.app;
let options = config.options;
let watcher = options.watcher;
let rootURL = options.rootURL === '' ? '/' : cleanBaseURL(options.rootURL);
let testsPath = `${rootURL}tests`;
app.use(async (req, _, next) => {
let results;
let watcherSuccess;
try {
results = await watcher;
watcherSuccess = true;
} catch (e) {
watcherSuccess = false;
// the build has failed, the middleware can safely be skipped.
// build error reporting is handled by:
// 1. watcher production stderr
// 2. watcher-middleware serving the error page
}
if (watcherSuccess) {
rewriteRequestUrlIfBasePageIsNeeded(req, testsPath, rootURL, results.directory);
}
next();
if (config.finally) {
config.finally();
}
});
}
};
function rewriteRequestUrlIfBasePageIsNeeded(req, testsPath, rootURL, directory) {
let acceptHeaders = req.headers.accept || [];
let hasHTMLHeader = acceptHeaders.indexOf('text/html') !== -1;
let hasWildcardHeader = acceptHeaders.indexOf('*/*') !== -1;
let isForTests = req.path.indexOf(testsPath) === 0;
logger.info('isForTests: %o', isForTests);
if (isForTests && (hasHTMLHeader || hasWildcardHeader) && req.method === 'GET') {
let assetPath = req.path.slice(rootURL.length);
let filePath = path.join(directory, assetPath);
if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
// N.B., `rootURL` will end with a slash as it went through `cleanBaseURL`
let newURL = `${rootURL}tests/index.html`;
logger.info('url: %s resolved to path: %s which is not a file. Assuming %s instead', req.path, filePath, newURL);
req.url = newURL;
}
}
}