UNPKG

flagpole

Version:

Simple and fast DOM integration and REST API testing framework.

394 lines (393 loc) 12.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const index_1 = require("./index"); const consoleline_1 = require("./consoleline"); const jsonresponse_1 = require("./jsonresponse"); const htmlresponse_1 = require("./htmlresponse"); const response_1 = require("./response"); const imageresponse_1 = require("./imageresponse"); const resourceresponse_1 = require("./resourceresponse"); const scriptresponse_1 = require("./scriptresponse"); const cssresponse_1 = require("./cssresponse"); const mock_1 = require("./mock"); let request = require('request'); class Scenario { constructor(suite, title, onDone) { this.log = []; this.failures = []; this.passes = []; this.initialized = null; this.start = null; this.end = null; this.requestStart = null; this.requestLoaded = null; this.responseType = response_1.ResponseType.html; this.url = null; this.waitToExecute = false; this.nextLabel = null; this.flipAssertion = false; this.optionalAssertion = false; this.ignoreAssertion = false; this._then = null; this._isMock = false; this.options = { method: 'GET', headers: {} }; this.initialized = Date.now(); this.suite = suite; this.title = title; this.onDone = onDone; this.subheading(title); } failed() { return (this.failures.length > 0); } passed() { return !!(this.end && this.failures.length == 0); } jsonBody(jsonObject) { this.header('Content-Type', 'application/json'); return this.body(JSON.stringify(jsonObject)); } body(str) { this.options.body = str; return this; } verifySslCert(verify) { this.options.strictSSL = verify; this.options.rejectUnauthorized = verify; return this; } proxy(proxyUri) { this.options.proxy = proxyUri; return this; } timeout(timeout) { this.options.timeout = timeout; return this; } wait(bool = true) { this.waitToExecute = bool; return this; } form(form) { this.options.form = form; return this; } maxRedirects(n) { this.options.maxRedirects = n; return this; } followRedirect(onRedirect) { this.options.followRedirect = onRedirect; return this; } auth(authorization) { this.options.auth = authorization; return this; } headers(headers) { this.options.headers = Object.assign(this.options.headers, headers); return this; } header(key, value) { this.options.headers = this.options.headers || {}; this.options.headers[key] = value; return this; } method(method) { this.options.method = method.toUpperCase(); return this; } isDone() { return (this.end !== null); } subheading(message) { this.log.push(new consoleline_1.SubheadingLine(message)); return this; } comment(message) { this.log.push(new consoleline_1.CommentLine(message)); return this; } assert(statement, message, actualValue) { if (!this.ignoreAssertion) { let passed = this.flipAssertion ? !statement : !!statement; if (this.flipAssertion) { message = 'NOT: ' + message; } if (this.optionalAssertion) { message += ' - Optional'; } if (passed) { this.pass(message); } else { if (actualValue) { message += ' (' + actualValue + ')'; } this.fail(message, this.optionalAssertion); } return this.reset(); } return this; } pass(message) { if (this.nextLabel) { message = this.nextLabel; this.nextLabel = null; } this.log.push(new consoleline_1.PassLine(message)); this.passes.push(message); return this; } fail(message, isOptional = false) { if (this.nextLabel) { message = this.nextLabel; this.nextLabel = null; } let line = new consoleline_1.FailLine(message); if (isOptional) { line.color = consoleline_1.ConsoleColor.FgMagenta; line.textSuffix = '(Optional)'; } this.log.push(line); if (!isOptional) { this.failures.push(message); } return this; } reset() { this.flipAssertion = false; this.optionalAssertion = false; return this; } not() { this.flipAssertion = true; return this; } optional() { this.optionalAssertion = true; return this; } ignore(assertions = true) { if (typeof assertions == 'boolean') { this.ignoreAssertion = assertions; } else if (typeof assertions == 'function') { this.ignore(true); assertions(); this.ignore(false); } return this; } executeWhenReady() { if (!this.waitToExecute && this.canExecute()) { this.execute(); } } open(url) { if (!this.hasExecuted()) { this.url = url; this._isMock = false; this.executeWhenReady(); } return this; } then(callback) { if (!this.hasExecuted()) { this._then = callback; this.executeWhenReady(); } return this; } assertions(callback) { return this.then(callback); } skip(message) { if (!this.hasExecuted()) { message = "Skipped" + (message ? ': ' + message : ''); this.start = Date.now(); this.log.push(new consoleline_1.CommentLine(message)); this.end = Date.now(); this.onDone(this); } return this; } getScenarioType() { if (this.responseType == response_1.ResponseType.json) { return { name: 'REST End Point', responseObject: jsonresponse_1.JsonResponse }; } else if (this.responseType == response_1.ResponseType.image) { return { name: 'Image', responseObject: imageresponse_1.ImageResponse }; } else if (this.responseType == response_1.ResponseType.script) { return { name: 'Script', responseObject: scriptresponse_1.ScriptResponse }; } else if (this.responseType == response_1.ResponseType.stylesheet) { return { name: 'Stylesheet', responseObject: cssresponse_1.CssResponse }; } else if (this.responseType == response_1.ResponseType.resource) { return { name: 'Resource', responseObject: resourceresponse_1.ResourceResponse }; } else { return { name: 'HTML Page', responseObject: htmlresponse_1.HtmlResponse }; } } processResponse(simplifiedResponse) { let scenarioType = this.getScenarioType(); this.requestLoaded = Date.now(); this.pass('Loaded ' + scenarioType.name + ' ' + this.url); if (this._then !== null && this.url !== null) { this._then(new scenarioType.responseObject(this, this.url, simplifiedResponse)); } this.done(); } executeRequest() { if (!this.requestStart && this.url !== null) { let scenario = this; this.requestStart = Date.now(); this.options.uri = this.suite.buildUrl(this.url); if (this.responseType == response_1.ResponseType.image) { require('probe-image-size')(this.options.uri, this.options, function (error, result) { if (!error) { scenario.processResponse({ statusCode: 200, body: JSON.stringify(result), headers: { 'content-type': result.mime } }); } else { scenario.fail('Failed to load image ' + scenario.url); scenario.done(); } }); } else { request(this.options, function (error, response, body) { if (!error) { scenario.processResponse(index_1.Flagpole.toSimplifiedResponse(response, body)); } else { scenario.fail('Failed to load ' + scenario.url); scenario.comment(error); scenario.done(); } }); } } } executeMock() { if (!this.requestStart && this.url !== null) { let scenario = this; this.requestStart = Date.now(); mock_1.Mock.loadLocalFile(this.url).then(function (mock) { scenario.processResponse(mock); }).catch(function () { scenario.fail('Failed to load page ' + scenario.url); scenario.done(); }); } } execute() { if (!this.hasExecuted() && this.url !== null) { this.start = Date.now(); if (this.waitToExecute && this.initialized !== null) { this.log.push(new consoleline_1.CommentLine('Waited ' + (this.start - this.initialized) + 'ms')); } this._isMock ? this.executeMock() : this.executeRequest(); } return this; } mock(localPath) { this.url = localPath; this._isMock = true; this.executeWhenReady(); return this; } label(message) { this.nextLabel = message; return this; } getTitle() { return this.title; } getLog() { return this.log; } getExecutionTime() { return (this.end !== null && this.start !== null) ? (this.end - this.start) : 0; } done() { this.end = Date.now(); this.log.push(new consoleline_1.CommentLine("Took " + this.getExecutionTime() + 'ms')); this.onDone(this); return this; } getUrl() { return this.url; } getRequestLoadTime() { return (this.requestLoaded && this.requestStart) ? (this.requestLoaded - this.requestStart) : null; } canExecute() { return (!this.hasExecuted() && this.url !== null && this._then !== null); } hasExecuted() { return this.start !== null; } hasFinished() { return this.hasExecuted() && this.end !== null; } setResponseType(type) { if (this.hasExecuted()) { throw new Error('Scenario was already executed. Can not change type.'); } this.responseType = type; return this; } image() { return this.setResponseType(response_1.ResponseType.image); } html() { return this.setResponseType(response_1.ResponseType.html); } json() { return this.setResponseType(response_1.ResponseType.json); } script() { return this.setResponseType(response_1.ResponseType.script); } stylesheet() { return this.setResponseType(response_1.ResponseType.stylesheet); } resource() { return this.setResponseType(response_1.ResponseType.resource); } } exports.Scenario = Scenario;