flagpole
Version:
Simple and fast DOM integration, headless or headful browser, and REST API testing framework.
477 lines • 15.8 kB
JavaScript
"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
const enums_1 = require("./enums");
const scenario_1 = require("./scenario");
const url_1 = require("url");
const flagpolereport_1 = require("./logging/flagpolereport");
const util_1 = require("./util");
const flagpoleexecutionoptions_1 = require("./flagpoleexecutionoptions");
class Suite {
constructor(title) {
this.scenarios = [];
this._subscribers = [];
this._errorCallbacks = [];
this._successCallbacks = [];
this._failureCallbacks = [];
this._finallyCallbacks = [];
this._beforeAllCallbacks = [];
this._afterAllCallbacks = [];
this._beforeEachCallbacks = [];
this._afterEachCallbacks = [];
this._beforeAllResolver = () => { };
this._finishedResolver = () => { };
this._baseUrl = null;
this._timeSuiteInitialized = Date.now();
this._timeSuiteExecuted = null;
this._timeSuiteFinished = null;
this._waitToExecute = false;
this._verifySslCert = true;
this._concurrencyLimit = 0;
this.error = this.catch;
this._title = title;
if (flagpoleexecutionoptions_1.FlagpoleExecution.opts.baseDomain) {
this._baseUrl = new url_1.URL(flagpoleexecutionoptions_1.FlagpoleExecution.opts.baseDomain);
}
this._beforeAllPromise = new Promise((resolve) => {
this._beforeAllResolver = resolve;
});
this._finishedPromise = new Promise((resolve) => {
this._finishedResolver = resolve;
});
}
get suite() {
return this;
}
get baseUrl() {
return this._baseUrl;
}
get failCount() {
let count = 0;
this.scenarios.forEach((scenario) => {
if (!scenario.hasPassed) {
count += 1;
}
});
return count;
}
get waitingToExecuteCount() {
let count = 0;
this.scenarios.forEach((scenario) => {
if (!scenario.hasExecuted) {
count += 1;
}
});
return count;
}
get executingCount() {
let count = 0;
this.scenarios.forEach((scenario) => {
if (scenario.hasExecuted && !scenario.hasFinished) {
count += 1;
}
});
return count;
}
get hasPassed() {
return this.scenarios.every(function (scenario) {
return scenario.hasPassed;
});
}
get hasFailed() {
return this.scenarios.some(function (scenario) {
return scenario.hasFailed;
});
}
get hasExecuted() {
return this._timeSuiteExecuted !== null;
}
get hasFinished() {
return this._timeSuiteFinished !== null;
}
get totalDuration() {
return this._timeSuiteFinished !== null
? this._timeSuiteFinished - this._timeSuiteInitialized
: null;
}
get executionDuration() {
return this._timeSuiteExecuted !== null && this._timeSuiteFinished !== null
? this._timeSuiteFinished - this._timeSuiteExecuted
: null;
}
get title() {
return this._title;
}
get finished() {
return this._finishedPromise;
}
get executionOptions() {
return flagpoleexecutionoptions_1.FlagpoleExecution.opts;
}
subscribe(callback) {
this._subscribers.push(callback);
return this;
}
verifySslCert(verify) {
this._verifySslCert = verify;
return this;
}
wait(bool = true) {
this._waitToExecute = bool;
return this;
}
setConcurrencyLimit(maxExecutions) {
this._concurrencyLimit = maxExecutions > 0 ? Math.floor(maxExecutions) : 0;
}
print(exitAfterPrint = true) {
const report = new flagpolereport_1.FlagpoleReport(this, flagpoleexecutionoptions_1.FlagpoleExecution.opts);
report.print().then(() => {
exitAfterPrint && util_1.exitProcess(this.hasPassed);
});
}
scenario(title, type, opts) {
const scenario = scenario_1.Scenario.create(this, title, type, opts, (scenario) => {
return this._onAfterScenarioFinished(scenario);
});
scenario.before((scenario) => {
return this._onBeforeScenarioExecutes(scenario);
});
scenario.after((scenario) => {
return this._onAfterScenarioExecutes(scenario);
});
scenario.error((errorMessage) => {
return this._fireError(errorMessage);
});
scenario.verifyCert(this._verifySslCert);
this._waitToExecute && scenario.wait();
this.scenarios.push(scenario);
return scenario;
}
json(title) {
return this.scenario(title, enums_1.ResponseType.json);
}
image(title) {
return this.scenario(title, enums_1.ResponseType.image);
}
video(title) {
return this.scenario(title, enums_1.ResponseType.video);
}
html(title) {
return this.scenario(title, enums_1.ResponseType.html);
}
stylesheet(title) {
return this.scenario(title, enums_1.ResponseType.stylesheet);
}
script(title) {
return this.scenario(title, enums_1.ResponseType.script);
}
resource(title) {
return this.scenario(title, enums_1.ResponseType.resource);
}
browser(title, opts = {}) {
return this.scenario(title, enums_1.ResponseType.browser, opts);
}
extjs(title, opts = {}) {
return this.scenario(title, enums_1.ResponseType.extjs, opts);
}
base(url) {
let baseUrl = "";
if (typeof url == "string") {
baseUrl = url;
}
else if (typeof url == "function") {
baseUrl = url.call(this, [this]);
}
else if (Object.keys(url).length > 0) {
baseUrl = url[flagpoleexecutionoptions_1.FlagpoleExecution.opts.environment];
if (!baseUrl) {
baseUrl = url[Object.keys(url)[0]];
}
}
if (baseUrl.length > 0) {
this._baseUrl = new url_1.URL(baseUrl);
}
else {
throw Error("Invalid base url.");
}
return this;
}
buildUrl(path) {
if (this._baseUrl === null) {
return path;
}
else if (/^https?:\/\//.test(path) || /^data:/.test(path)) {
return path;
}
else if (/^\//.test(path)) {
return this._baseUrl.protocol + "//" + this._baseUrl.host + path;
}
return new url_1.URL(path, this._baseUrl.href).href;
}
execute() {
if (this.hasExecuted) {
throw new Error(`Suite already executed.`);
}
this._timeSuiteExecuted = Date.now();
this.scenarios.forEach(function (scenario) {
scenario.execute();
});
return this;
}
beforeAll(callback) {
if (this.hasExecuted) {
throw new Error("Can not add beforeAll callbacks after execution has started.");
}
this._beforeAllCallbacks.push(callback);
return this;
}
beforeEach(callback) {
if (this.hasExecuted) {
throw new Error("Can not add beforeEach callbacks after execution has started.");
}
this._beforeEachCallbacks.push(callback);
return this;
}
afterEach(callback) {
if (this.hasFinished) {
throw new Error("Can not add afterEach callbacks after execution has finished.");
}
this._afterEachCallbacks.push(callback);
return this;
}
afterAll(callback) {
if (this.hasFinished) {
throw new Error("Can not add afterAll callbacks after execution has finished.");
}
this._afterAllCallbacks.push(callback);
return this;
}
catch(callback) {
if (this.hasFinished) {
throw new Error("Can not add catch callbacks after execution has finished.");
}
this._errorCallbacks.push(callback);
return this;
}
success(callback) {
if (this.hasFinished) {
throw new Error("Can not add success callbacks after execution has finished.");
}
this._successCallbacks.push(callback);
return this;
}
failure(callback) {
if (this.hasFinished) {
throw new Error("Can not add failure callbacks after execution has finished.");
}
this._failureCallbacks.push(callback);
return this;
}
finally(callback) {
if (this.hasFinished) {
throw new Error("Can not add finally callbacks after execution has finished.");
}
this._finallyCallbacks.push(callback);
return this;
}
promise() {
return new Promise((resolve, reject) => {
this.success(resolve);
this.error(reject);
this.failure(reject);
});
}
_haveAllScenariosFinished() {
return this.scenarios.every(function (scenario) {
return scenario.hasFinished;
});
}
_fireBeforeAll() {
const suite = this;
this._timeSuiteExecuted = Date.now();
return new Promise((resolve, reject) => {
Promise.mapSeries(this._beforeAllCallbacks, (_then) => {
return _then(suite);
})
.then(() => {
this._publish(enums_1.SuiteStatusEvent.beforeAllExecute);
this._beforeAllResolver();
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireBeforeEach(scenario) {
const suite = this;
return new Promise((resolve, reject) => {
Promise.mapSeries(this._beforeEachCallbacks, (_then) => {
return _then.apply(suite, [scenario]);
})
.then(() => {
this._publish(enums_1.SuiteStatusEvent.beforeEachExecute);
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireAfterEach(scenario) {
const suite = this;
return new Promise((resolve, reject) => {
Promise.mapSeries(this._afterEachCallbacks, (_then) => {
return _then.apply(suite, [scenario]);
})
.then(() => {
this._publish(enums_1.SuiteStatusEvent.afterEachExecute);
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireAfterAll() {
const suite = this;
this._timeSuiteFinished = Date.now();
return new Promise((resolve, reject) => {
Promise.mapSeries(this._afterAllCallbacks, (_then) => {
return _then.apply(suite, [suite]);
})
.then(() => {
this._publish(enums_1.SuiteStatusEvent.afterAllExecute);
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireSuccess() {
const suite = this;
return new Promise((resolve, reject) => {
Promise.mapSeries(this._successCallbacks, (_then) => {
return _then.apply(suite, [suite]);
})
.then(() => {
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireFailure() {
const suite = this;
return new Promise((resolve, reject) => {
Promise.mapSeries(this._failureCallbacks, (_then) => {
return _then.apply(suite, [suite]);
})
.then(() => {
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireError(errorMessage) {
const suite = this;
return new Promise((resolve, reject) => {
Promise.mapSeries(this._errorCallbacks, (_then) => {
return _then.apply(suite, [errorMessage]);
})
.then(() => {
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_fireFinally() {
const suite = this;
return new Promise((resolve, reject) => {
Promise.mapSeries(this._finallyCallbacks, (_then) => {
return _then.apply(suite, [suite]);
})
.then(() => {
this._publish(enums_1.SuiteStatusEvent.finished);
this._finishedResolver();
resolve();
})
.catch((err) => {
reject(err);
});
});
}
_onBeforeScenarioExecutes(scenario) {
return __awaiter(this, void 0, void 0, function* () {
if (scenario.hasExecuted && !this.hasExecuted) {
yield this._fireBeforeAll();
}
yield this._beforeAllResolved();
yield this._fireBeforeEach(scenario);
return scenario;
});
}
_onAfterScenarioExecutes(scenario) {
return __awaiter(this, void 0, void 0, function* () {
yield this._fireAfterEach(scenario);
return scenario;
});
}
_onAfterScenarioFinished(scenario) {
return __awaiter(this, void 0, void 0, function* () {
if (this._haveAllScenariosFinished() && !this.hasFinished) {
yield this._fireAfterAll();
this.hasPassed ? yield this._fireSuccess() : yield this._fireFailure();
yield this._fireFinally();
if (flagpoleexecutionoptions_1.FlagpoleExecution.opts.automaticallyPrintToConsole) {
this.print(flagpoleexecutionoptions_1.FlagpoleExecution.opts.exitOnDone);
}
else {
flagpoleexecutionoptions_1.FlagpoleExecution.opts.exitOnDone && util_1.exitProcess(this.hasPassed);
}
}
});
}
_beforeAllResolved() {
return __awaiter(this, void 0, void 0, function* () {
return new Promise((resolve, reject) => {
this._beforeAllPromise
.then(() => {
resolve(true);
})
.catch((ex) => {
reject(ex);
});
});
});
}
_publish(statusEvent) {
this._subscribers.forEach((callback) => {
callback(this, statusEvent);
});
}
_executeNext() {
this.scenarios.some((scenario) => {
if (!scenario.hasExecuted && scenario.canExecute) {
scenario.execute();
return true;
}
});
}
}
exports.Suite = Suite;
//# sourceMappingURL=suite.js.map