ivr-tester
Version:
An automated testing framework for IVR call flows
132 lines (131 loc) • 5.81 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.IvrTester = void 0;
const TwilioCallServer_1 = require("./testing/TwilioCallServer");
const PluginManager_1 = require("./plugins/PluginManager");
const TwilioCaller_1 = require("./call/TwilioCaller");
const IteratingTestAssigner_1 = require("./testing/IteratingTestAssigner");
const MediaStreamRecorder_1 = require("./call/recording/MediaStreamRecorder");
const TestExecutor_1 = require("./testing/TestExecutor");
const AudioPlaybackCaller_1 = require("./call/AudioPlaybackCaller");
const consoleUserInterface_1 = require("./testing/ui/consoleUserInterface");
const StopTestRunnerWhenTestsComplete_1 = require("./testing/StopTestRunnerWhenTestsComplete");
const callConnectedTimeout_1 = require("./testing/callConnectedTimeout");
const TranscriptRecorder_1 = require("./call/recording/TranscriptRecorder");
const validateConfig_1 = require("./configuration/validateConfig");
const validateAndEnrichScenario_1 = require("./configuration/scenario/validateAndEnrichScenario");
const validateTestSubject_1 = require("./configuration/call/validateTestSubject");
function createTestRunnerManager() {
let callback = undefined;
let stopped = false;
let stoppedDueToFailure = false;
return {
setOnStopCallback(cb) {
callback = cb;
if (stopped) {
callback(stoppedDueToFailure);
}
},
testRunner: {
stop(failure = false) {
stopped = true;
stoppedDueToFailure = failure;
if (callback) {
callback(stoppedDueToFailure);
}
},
},
};
}
function createPluginManager(config) {
return new PluginManager_1.PluginManager([
new StopTestRunnerWhenTestsComplete_1.StopTestRunnerWhenTestsComplete(),
consoleUserInterface_1.consoleUserInterface(),
callConnectedTimeout_1.callConnectedTimeout(config),
MediaStreamRecorder_1.mediaStreamRecorderPlugin(config),
TranscriptRecorder_1.transcriptRecorderPlugin(config),
]);
}
class IvrTester {
constructor(configuration) {
this.running = false;
const result = validateConfig_1.validateConfig(configuration);
if (result.error) {
throw result.error;
}
if (!result.config) {
throw new Error("Error loading configuration");
}
this.config = result.config;
this.pluginManager = createPluginManager(this.config);
}
async run(testSubject, scenario) {
if (this.running) {
throw new Error("Instance of IvrTester can only run a single suite of scenarios");
}
this.running = true;
const testSubjectValidationResult = validateTestSubject_1.validateTestSubject(testSubject);
if (testSubjectValidationResult.error) {
throw testSubjectValidationResult.error;
}
const validationResult = validateAndEnrichScenario_1.validateAndEnrichScenario(scenario);
if (validationResult.error) {
throw validationResult.error;
}
const scenarios = validationResult.scenarios;
await this.preflightChecks();
const callServer = new TwilioCallServer_1.TwilioCallServer(this.config.dtmfGenerator, new IteratingTestAssigner_1.IteratingTestAssigner(scenarios), TestExecutor_1.testExecutor(this.config.transcriber));
const twilioClient = this.config.twilioClientFactory(this.config.twilioAuth);
const caller = Buffer.isBuffer(testSubject)
? new AudioPlaybackCaller_1.AudioPlaybackCaller()
: new TwilioCaller_1.TwilioCaller(twilioClient);
const testRunnerManager = createTestRunnerManager();
this.pluginManager.initialise(testRunnerManager.testRunner);
const serverUrl = await callServer.listen(this.config.localServerPort);
this.pluginManager.serverListening(callServer);
const calls = Promise.all(scenarios.map(() => caller
.call(testSubject, this.config.publicServerUrl || serverUrl)
.then((callRequested) => this.pluginManager.callRequested(callRequested, scenarios.length))
.catch((error) => {
this.pluginManager.callRequestErrored(new Error(error));
throw error;
})));
return new Promise((resolve, reject) => {
calls
.then(() => {
callServer.on("stopped", reject);
callServer.on("error", reject);
testRunnerManager.setOnStopCallback((failure) => {
callServer.off("stopped", reject);
callServer.off("error", reject);
callServer
.stop()
.catch((err) => err && console.error(err))
.finally(() => {
if (failure) {
reject();
}
else {
resolve();
}
});
});
})
.catch((error) => {
callServer.off("stopped", reject);
callServer.off("error", reject);
callServer
.stop()
.catch((err) => err && console.error(err))
.finally(() => reject(error));
});
});
}
async preflightChecks() {
const checkResults = await this.config.transcriber.checkCanRun();
if (checkResults.canRun === false) {
throw new Error(`Error with the transcriber you've chosen:\n${checkResults.reason}`);
}
}
}
exports.IvrTester = IvrTester;