@ply-ct/ply
Version:
REST API Automated Testing
170 lines (160 loc) • 6.25 kB
text/typescript
import * as fs from 'fs';
import * as path from 'path';
import * as glob from 'glob';
import * as tsNode from 'ts-node';
import { Plier } from './ply';
import { Config, Defaults, PlyOptions, RunOptions } from './options';
import { Location } from './location';
import { Storage } from './storage';
import { Retrieval } from './retrieval';
import { Import } from './import/import';
import { OpenApi } from './plyex/openapi';
import { Plyex } from './plyex/plyex';
import * as yaml from './yaml';
import { ImportOptions } from './import/model';
import { ReporterFactory } from './report/report';
const start = Date.now();
tsNode.register({ transpileOnly: true });
const opts = new Config(new Defaults(), true).options;
const { runOptions, ...options } = opts as PlyOptions & { runOptions?: RunOptions};
const plier = new Plier(options);
if (runOptions?.import) {
plier.logger.debug('Options', options);
const importer = new Import(runOptions.import as any, plier.logger);
try {
let valuesLoc = `${options.testsLocation}/values`;
if (options.valuesFiles) {
const firstEnabledValFile = Object.keys(options.valuesFiles).find((vf) => {
return options.valuesFiles[vf];
});
if (firstEnabledValFile) valuesLoc = path.dirname(firstEnabledValFile);
}
const opts: ImportOptions = {
testsLocation: options.testsLocation,
valuesLocation: valuesLoc,
indent: options.prettyIndent,
importToSuite: runOptions.importToSuite
};
for (const path of options.args) {
plier.logger.info('Importing', path);
importer.doImport(new Retrieval(path), opts);
}
} catch (err: unknown) {
plier.logger.error(`${err}`, err);
process.exit(1);
}
} else if (runOptions?.report) {
plier.logger.debug('Options', options);
const format: string = runOptions.report;
const factory = new ReporterFactory(format);
factory
.createReporter()
.then((reporter) => {
reporter.report({
format: factory.format,
output: opts.outputFile || `${opts.logLocation}/ply-runs.${factory.format}`,
runsLocation: `${opts.logLocation}/runs`,
logger: plier.logger,
indent: opts.prettyIndent
});
})
.catch((err) => {
plier.logger.error(err.message, err);
process.exit(1);
});
} else if (runOptions?.openapi) {
plier.logger.debug('Options', options);
const plyex = new Plyex(runOptions.openapi, plier.logger);
for (const path of options.args) {
const contents = fs.readFileSync(path, { encoding: 'utf8' });
plier.logger.info('Overwriting', path);
const isYaml = !contents.startsWith('{');
const openApi: OpenApi = isYaml ? yaml.load(path, contents) : JSON.parse(contents);
plyex
.augment(openApi)
.then((augmented) => {
let updated: string;
if (isYaml) updated = yaml.dump(augmented, options.prettyIndent);
else updated = JSON.stringify(augmented, null, options.prettyIndent);
fs.writeFileSync(path, updated, { encoding: 'utf8' });
})
.catch(console.error);
}
} else {
let paths: string[] = [];
let args: string[] = options.args;
const globOptions = {
cwd: options.testsLocation,
ignore: options.ignore
};
if (args && args.length > 0) {
// ignore skip unless passed on command-line since tests specified
if (!options.skip) plier.options.skip = '';
// make arg paths relative to tests loc
if (options.testsLocation !== '.') {
args = args.map((arg) => {
const argLoc = new Location(arg);
if (argLoc.isChildOf(options.testsLocation)) {
return argLoc.relativeTo(options.testsLocation);
} else {
plier.logger.error(
`WARNING: ${arg} is not under testsLocation ${options.testsLocation}`
);
}
return arg;
});
}
for (const arg of args) {
const hash = arg.indexOf('#');
if (hash > 0) {
paths.push(arg);
} else {
// treat as glob pattern
for (const file of glob.sync(arg, globOptions)) {
paths.push(file);
}
if (paths.length === 0) {
throw new Error(`Test files(s) not found: ${args}`);
}
}
}
} else {
paths = [
...glob.sync(options.requestFiles, globOptions),
...glob.sync(options.caseFiles, globOptions),
...glob.sync(options.flowFiles, globOptions)
];
}
paths = paths.map((p) => {
return path.isAbsolute(p) ? p : options.testsLocation + path.sep + p;
});
plier
.find(paths)
.then((plyees) => {
plier.logger.debug('Plyees', plyees);
plier
.run(plyees, runOptions)
.then((results) => {
plier.logger.error('\nOverall Results: ' + JSON.stringify(results));
plier.logger.error(`Overall Time: ${Date.now() - start} ms`);
// json reporter overrides overall outputFile
if (plier.options.outputFile && plier.options.reporter !== 'json') {
new Storage(plier.options.outputFile).write(
JSON.stringify(results, null, plier.options.prettyIndent)
);
}
if (results.Failed || results.Errored) {
process.exit(1);
}
})
.catch((err) => {
plier.logger.error(err);
process.exit(1);
});
})
.catch((err) => {
plier.logger.error(err);
process.exit(1);
});
}