flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
241 lines • 10.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const webserver_1 = require("../webserver");
const cli_1 = require("./cli");
const url_1 = require("url");
const testrunner_1 = require("./testrunner");
const __1 = require("..");
const fs = require('fs');
const open = require('open');
function serve() {
const getSuites = () => {
const suites = cli_1.Cli.config.getSuites();
let output = {};
suites.forEach((suite) => {
output[suite.name] = {
name: suite.name,
path: suite.getPath()
};
});
return output;
};
const getTemplate = (output, nav) => {
let template = fs.readFileSync(`${__dirname}/report.html`, 'utf8');
nav = nav || `
<a href="/">Project Home</a>
`;
template = template.replace('${output}', output).replace('${nav}', nav);
return template;
};
const fileNotFound = () => {
return getTemplate('File not found.');
};
const routes = {
'GET /api/suites': (url, response) => {
response.end(JSON.stringify({
suites: getSuites()
}));
},
'POST /rm': (url, response) => {
const env = url.searchParams.get('env');
const suite = url.searchParams.get('suite');
if (suite) {
cli_1.Cli.config.removeSuite(suite);
cli_1.Cli.config.save()
.then(() => {
response.end(getTemplate(`Removed suite <em>${suite}</em>, but did not delete the file. <a href="/">Back</a>`));
})
.catch((ex) => {
response.end(getTemplate(`Error: ${ex}`));
});
}
else if (env) {
cli_1.Cli.config.removeEnvironment(env);
cli_1.Cli.config.save()
.then(() => {
response.end(getTemplate(`Removed environment <em>${env}</em>. <a href="/">Back</a>`));
})
.catch((ex) => {
response.end(getTemplate(`Error: ${ex}`));
});
}
},
'POST /addEnv': (url, response) => {
const envName = url.searchParams.get('name');
const defaultDomain = url.searchParams.get('domain');
if (envName) {
if (cli_1.Cli.config.environments[envName]) {
response.end(getTemplate('Error: Environment name is already taken.'));
}
else {
cli_1.Cli.config.addEnvironment(envName, { defaultDomain: defaultDomain });
cli_1.Cli.config.save()
.then(() => {
response.end(getTemplate(`Added new environment <em>${envName}</em>. <a href="/">Back</a>`));
})
.catch((ex) => {
response.end(getTemplate(`Error: ${ex}`));
});
}
}
},
'POST /run': (url, response) => {
const suiteName = url.searchParams.get('suite');
if (suiteName && cli_1.Cli.config.suites[suiteName]) {
let opts = '-h -o json';
if (__1.Flagpole.getEnvironment()) {
opts += ' -e ' + __1.Flagpole.getEnvironment();
}
testrunner_1.TestRunner.execute(cli_1.Cli.config.suites[suiteName].getPath(), opts)
.then((result) => {
const json = JSON.parse(result.output.join(' '));
let output = `<h2>${json.title}</h2>`;
json.scenarios.forEach((scenario) => {
output += `<article><h3>${scenario.title}</h3>`;
output += '<ul>';
scenario.log.forEach((logLine) => {
output += `<li class="${logLine.type.toLowerCase()}">${logLine.message}</li>`;
});
output += '</ul></article>';
});
response.end(getTemplate(output));
})
.catch((err) => {
response.end(getTemplate(err));
});
}
else {
response.end(fileNotFound());
}
}
};
const handler = (request, response) => {
const requestPath = request.url || '/';
const method = (request.method || 'GET').toUpperCase();
const url = new url_1.URL(requestPath, `http://localhost:${server.httpPort}`);
const route = `${method} ${url.pathname}`;
if (routes[route]) {
routes[route](url, response);
}
else {
const suites = cli_1.Cli.config.getSuites();
let output = `
<ul>
<li>Project Name: ${cli_1.Cli.config.project.name}</li>
<li>Config Path: ${cli_1.Cli.configPath}</li>
<li>Root Path: ${cli_1.Cli.rootPath}</li>
<li>Environment: ${__1.Flagpole.getEnvironment()}</li>
</ul>
<h2>List of Suites</h2>
<table>
<thead>
<tr>
<th>Suite Name</th>
<th colspan="3">Actions</th>
</tr>
</thead>
<tbody>
`;
suites.forEach((suite) => {
output += `
<tr>
<td>${suite.name}</td>
<td>
<form method="POST" action="/run?suite=${suite.name}">
<button type="submit">Run</button>
</form>
</td>
<td>
<form method="GET" action="/add_scenario?suite=${suite.name}">
<button type="button" onclick="alert('Not yet supported')">Add Scenario</button>
</form>
</td>
<td>
<form method="POST" id="rm_suite_${suite.name}">
<button type="button" onclick="removeSuite('${suite.name}')">Remove</button>
</form>
</td>
</tr>
`;
});
output += `
</tbody>
</table>
<aside>
<form method="GET" action="/add_suite">
<button type="button" onclick="alert('Not yet supported')">Add Suite</button>
</form>
</aside>
`;
output += `
<h2>List of Environments</h2>
<table>
<thead>
<tr>
<th>Suite Name</th>
<th>Default Domain</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
`;
cli_1.Cli.config.getEnvironments().forEach((env) => {
output += `
<tr>
<td>${env.name}</td>
<td>${env.defaultDomain}</td>
<td>
<form method="POST" action="/rm?env=${env.name}" id="rm_env_${env.name}">
<button type="button" onclick="removeEnv('${env.name}')">Remove</button>
</form>
</td>
</tr>
`;
});
output += `
</tbody>
</table>
<aside>
<form method="POST" id="addEnv">
<button type="button" onclick="addEnv()">Add Environment</button>
</form>
</aside>
<script>
function addEnv() {
const envName = prompt('Environment Name').trim().replace(' ', '_');
if (envName) {
const defaultDomain = (prompt('Default Domain') || '').replace(' ', '');
const form = document.querySelector('#addEnv');
form.setAttribute('action', '/addEnv?name=' + envName + '&domain=' + defaultDomain);
form.submit();
}
}
function removeEnv(envName) {
const yes = confirm('Remove this environment ' + envName + '?')
if (yes) {
const form = document.querySelector('#rm_env_' + envName);
form.setAttribute('action', '/rm?env=' + envName);
form.submit();
}
}
function removeSuite(suiteName) {
const yes = confirm('Remove this suite ' + suiteName + '?')
if (yes) {
const form = document.querySelector('#rm_suite_' + suiteName);
form.setAttribute('action', '/rm?suite=' + suiteName);
form.submit();
}
}
</script>
`;
response.end(getTemplate(output));
}
};
const server = new webserver_1.WebServer(handler);
server.listen().then(() => {
console.log(`Server listening on port ${server.httpPort}`);
open(`http://localhost:${server.httpPort}/`);
});
}
exports.serve = serve;
//# sourceMappingURL=serve.js.map