testcafe
Version:
Automated browser testing for the modern web development stack.
110 lines • 16.8 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const testcafe_hammerhead_1 = require("testcafe-hammerhead");
const hook_1 = __importDefault(require("./hook"));
const useragent_1 = require("useragent");
const test_run_tracker_1 = __importDefault(require("../test-run-tracker"));
const re_executable_promise_1 = __importDefault(require("../../utils/re-executable-promise"));
const runtime_1 = require("../../errors/runtime");
const types_1 = require("../../errors/types");
const DEFAULT_OPTIONS = {
logRequestHeaders: false,
logRequestBody: false,
stringifyRequestBody: false,
logResponseHeaders: false,
logResponseBody: false,
stringifyResponseBody: false
};
class RequestLoggerImplementation extends hook_1.default {
constructor(requestFilterRuleInit, options) {
options = Object.assign({}, DEFAULT_OPTIONS, options);
RequestLoggerImplementation._assertLogOptions(options);
const configureResponseEventOptions = new testcafe_hammerhead_1.ConfigureResponseEventOptions(options.logResponseHeaders, options.logResponseBody);
super(requestFilterRuleInit, configureResponseEventOptions);
this.options = options;
this._internalRequests = {};
}
static _assertLogOptions(logOptions) {
if (!logOptions.logRequestBody && logOptions.stringifyRequestBody)
throw new runtime_1.APIError('RequestLogger', types_1.RUNTIME_ERRORS.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the request body because it is not logged. Specify { logRequestBody: true } in log options.');
if (!logOptions.logResponseBody && logOptions.stringifyResponseBody)
throw new runtime_1.APIError('RequestLogger', types_1.RUNTIME_ERRORS.requestHookConfigureAPIError, 'RequestLogger', 'Cannot stringify the response body because it is not logged. Specify { logResponseBody: true } in log options.');
}
async onRequest(event) {
const userAgent = useragent_1.parse(event._requestInfo.userAgent).toString();
const loggedReq = {
id: event._requestInfo.requestId,
testRunId: event._requestInfo.sessionId,
userAgent,
request: {
url: event._requestInfo.url,
method: event._requestInfo.method,
}
};
if (this.options.logRequestHeaders)
loggedReq.request.headers = Object.assign({}, event._requestInfo.headers);
if (this.options.logRequestBody)
loggedReq.request.body = this.options.stringifyRequestBody ? event._requestInfo.body.toString() : event._requestInfo.body;
this._internalRequests[loggedReq.id] = loggedReq;
}
async onResponse(event) {
const loggerReq = this._internalRequests[event.requestId];
// NOTE: If the 'clear' method is called during a long running request,
// we should not save a response part - request part has been already removed.
if (!loggerReq)
return;
loggerReq.response = {};
loggerReq.response.statusCode = event.statusCode;
if (this.options.logResponseHeaders)
loggerReq.response.headers = Object.assign({}, event.headers);
if (this.options.logResponseBody) {
loggerReq.response.body = this.options.stringifyResponseBody && event.body
? event.body.toString()
: event.body;
}
}
_prepareInternalRequestInfo() {
const testRun = test_run_tracker_1.default.resolveContextTestRun();
let preparedRequests = Object.values(this._internalRequests);
if (testRun)
preparedRequests = preparedRequests.filter(r => r.testRunId === testRun.id);
return preparedRequests;
}
_getCompletedRequests() {
return this._prepareInternalRequestInfo().filter(r => r.response);
}
// API
contains(predicate) {
return re_executable_promise_1.default.fromFn(async () => {
return !!this._getCompletedRequests().find(predicate);
});
}
count(predicate) {
return re_executable_promise_1.default.fromFn(async () => {
return this._getCompletedRequests().filter(predicate).length;
});
}
clear() {
const testRun = test_run_tracker_1.default.resolveContextTestRun();
if (testRun) {
Object.keys(this._internalRequests).forEach(id => {
if (this._internalRequests[id].testRunId === testRun.id)
delete this._internalRequests[id];
});
}
else
this._internalRequests = {};
}
get requests() {
return this._prepareInternalRequestInfo();
}
}
function createRequestLogger(requestFilterRuleInit, logOptions) {
return new RequestLoggerImplementation(requestFilterRuleInit, logOptions);
}
exports.default = createRequestLogger;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVxdWVzdC1sb2dnZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvYXBpL3JlcXVlc3QtaG9va3MvcmVxdWVzdC1sb2dnZXIuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSw2REFBb0U7QUFDcEUsa0RBQWlDO0FBQ2pDLHlDQUFvRDtBQUNwRCwyRUFBaUQ7QUFDakQsOEZBQW9FO0FBQ3BFLGtEQUFnRDtBQUNoRCw4Q0FBb0Q7QUFFcEQsTUFBTSxlQUFlLEdBQUc7SUFDcEIsaUJBQWlCLEVBQU0sS0FBSztJQUM1QixjQUFjLEVBQVMsS0FBSztJQUM1QixvQkFBb0IsRUFBRyxLQUFLO0lBQzVCLGtCQUFrQixFQUFLLEtBQUs7SUFDNUIsZUFBZSxFQUFRLEtBQUs7SUFDNUIscUJBQXFCLEVBQUUsS0FBSztDQUMvQixDQUFDO0FBRUYsTUFBTSwyQkFBNEIsU0FBUSxjQUFXO0lBQ2pELFlBQWEscUJBQXFCLEVBQUUsT0FBTztRQUN2QyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsZUFBZSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3RELDJCQUEyQixDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRXZELE1BQU0sNkJBQTZCLEdBQUcsSUFBSSxtREFBNkIsQ0FBQyxPQUFPLENBQUMsa0JBQWtCLEVBQUUsT0FBTyxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBRTdILEtBQUssQ0FBQyxxQkFBcUIsRUFBRSw2QkFBNkIsQ0FBQyxDQUFDO1FBRTVELElBQUksQ0FBQyxPQUFPLEdBQUcsT0FBTyxDQUFDO1FBRXZCLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxFQUFFLENBQUM7SUFDaEMsQ0FBQztJQUVELE1BQU0sQ0FBQyxpQkFBaUIsQ0FBRSxVQUFVO1FBQ2hDLElBQUksQ0FBQyxVQUFVLENBQUMsY0FBYyxJQUFJLFVBQVUsQ0FBQyxvQkFBb0I7WUFDN0QsTUFBTSxJQUFJLGtCQUFRLENBQUMsZUFBZSxFQUFFLHNCQUFjLENBQUMsNEJBQTRCLEVBQUUsZUFBZSxFQUFFLDhHQUE4RyxDQUFDLENBQUM7UUFFdE4sSUFBSSxDQUFDLFVBQVUsQ0FBQyxlQUFlLElBQUksVUFBVSxDQUFDLHFCQUFxQjtZQUMvRCxNQUFNLElBQUksa0JBQVEsQ0FBQyxlQUFlLEVBQUUsc0JBQWMsQ0FBQyw0QkFBNEIsRUFBRSxlQUFlLEVBQUUsZ0hBQWdILENBQUMsQ0FBQztJQUM1TixDQUFDO0lBRUQsS0FBSyxDQUFDLFNBQVMsQ0FBRSxLQUFLO1FBQ2xCLE1BQU0sU0FBUyxHQUFHLGlCQUFjLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztRQUUxRSxNQUFNLFNBQVMsR0FBRztZQUNkLEVBQUUsRUFBUyxLQUFLLENBQUMsWUFBWSxDQUFDLFNBQVM7WUFDdkMsU0FBUyxFQUFFLEtBQUssQ0FBQyxZQUFZLENBQUMsU0FBUztZQUN2QyxTQUFTO1lBQ1QsT0FBTyxFQUFJO2dCQUNQLEdBQUcsRUFBSyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUc7Z0JBQzlCLE1BQU0sRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLE1BQU07YUFDcEM7U0FDSixDQUFDO1FBRUYsSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQjtZQUM5QixTQUFTLENBQUMsT0FBTyxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLEVBQUUsRUFBRSxLQUFLLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRTlFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxjQUFjO1lBQzNCLFNBQVMsQ0FBQyxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsb0JBQW9CLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLElBQUksQ0FBQztRQUU5SCxJQUFJLENBQUMsaUJBQWlCLENBQUMsU0FBUyxDQUFDLEVBQUUsQ0FBQyxHQUFHLFNBQVMsQ0FBQztJQUNyRCxDQUFDO0lBRUQsS0FBSyxDQUFDLFVBQVUsQ0FBRSxLQUFLO1FBQ25CLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUMsU0FBUyxDQUFDLENBQUM7UUFFMUQsdUVBQXVFO1FBQ3ZFLDhFQUE4RTtRQUM5RSxJQUFJLENBQUMsU0FBUztZQUNWLE9BQU87UUFFWCxTQUFTLENBQUMsUUFBUSxHQUFjLEVBQUUsQ0FBQztRQUNuQyxTQUFTLENBQUMsUUFBUSxDQUFDLFVBQVUsR0FBRyxLQUFLLENBQUMsVUFBVSxDQUFDO1FBRWpELElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxrQkFBa0I7WUFDL0IsU0FBUyxDQUFDLFFBQVEsQ0FBQyxPQUFPLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBRWxFLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLEVBQUU7WUFDOUIsU0FBUyxDQUFDLFFBQVEsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxxQkFBcUIsSUFBSSxLQUFLLENBQUMsSUFBSTtnQkFDdEUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUN2QixDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQztTQUNwQjtJQUNMLENBQUM7SUFFRCwyQkFBMkI7UUFDdkIsTUFBTSxPQUFPLEdBQVUsMEJBQWMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQzlELElBQUksZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQztRQUU3RCxJQUFJLE9BQU87WUFDUCxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxLQUFLLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUVoRixPQUFPLGdCQUFnQixDQUFDO0lBQzVCLENBQUM7SUFFRCxxQkFBcUI7UUFDakIsT0FBTyxJQUFJLENBQUMsMkJBQTJCLEVBQUUsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUVELE1BQU07SUFDTixRQUFRLENBQUUsU0FBUztRQUNmLE9BQU8sK0JBQW1CLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ3pDLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUMxRCxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxLQUFLLENBQUUsU0FBUztRQUNaLE9BQU8sK0JBQW1CLENBQUMsTUFBTSxDQUFDLEtBQUssSUFBSSxFQUFFO1lBQ3pDLE9BQU8sSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLE1BQU0sQ0FBQztRQUNqRSxDQUFDLENBQUMsQ0FBQztJQUNQLENBQUM7SUFFRCxLQUFLO1FBQ0QsTUFBTSxPQUFPLEdBQUcsMEJBQWMsQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBRXZELElBQUksT0FBTyxFQUFFO1lBQ1QsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLEVBQUU7Z0JBQzdDLElBQUksSUFBSSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsQ0FBQyxDQUFDLFNBQVMsS0FBSyxPQUFPLENBQUMsRUFBRTtvQkFDbkQsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDMUMsQ0FBQyxDQUFDLENBQUM7U0FDTjs7WUFFRyxJQUFJLENBQUMsaUJBQWlCLEdBQUcsRUFBRSxDQUFDO0lBQ3BDLENBQUM7SUFFRCxJQUFJLFFBQVE7UUFDUixPQUFPLElBQUksQ0FBQywyQkFBMkIsRUFBRSxDQUFDO0lBQzlDLENBQUM7Q0FDSjtBQUVELFNBQXdCLG1CQUFtQixDQUFFLHFCQUFxQixFQUFFLFVBQVU7SUFDMUUsT0FBTyxJQUFJLDJCQUEyQixDQUFDLHFCQUFxQixFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQzlFLENBQUM7QUFGRCxzQ0FFQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zIH0gZnJvbSAndGVzdGNhZmUtaGFtbWVyaGVhZCc7XG5pbXBvcnQgUmVxdWVzdEhvb2sgZnJvbSAnLi9ob29rJztcbmltcG9ydCB7IHBhcnNlIGFzIHBhcnNlVXNlckFnZW50IH0gZnJvbSAndXNlcmFnZW50JztcbmltcG9ydCB0ZXN0UnVuVHJhY2tlciBmcm9tICcuLi90ZXN0LXJ1bi10cmFja2VyJztcbmltcG9ydCBSZUV4ZWN1dGFibGVQcm9taXNlIGZyb20gJy4uLy4uL3V0aWxzL3JlLWV4ZWN1dGFibGUtcHJvbWlzZSc7XG5pbXBvcnQgeyBBUElFcnJvciB9IGZyb20gJy4uLy4uL2Vycm9ycy9ydW50aW1lJztcbmltcG9ydCB7IFJVTlRJTUVfRVJST1JTIH0gZnJvbSAnLi4vLi4vZXJyb3JzL3R5cGVzJztcblxuY29uc3QgREVGQVVMVF9PUFRJT05TID0ge1xuICAgIGxvZ1JlcXVlc3RIZWFkZXJzOiAgICAgZmFsc2UsXG4gICAgbG9nUmVxdWVzdEJvZHk6ICAgICAgICBmYWxzZSxcbiAgICBzdHJpbmdpZnlSZXF1ZXN0Qm9keTogIGZhbHNlLFxuICAgIGxvZ1Jlc3BvbnNlSGVhZGVyczogICAgZmFsc2UsXG4gICAgbG9nUmVzcG9uc2VCb2R5OiAgICAgICBmYWxzZSxcbiAgICBzdHJpbmdpZnlSZXNwb25zZUJvZHk6IGZhbHNlXG59O1xuXG5jbGFzcyBSZXF1ZXN0TG9nZ2VySW1wbGVtZW50YXRpb24gZXh0ZW5kcyBSZXF1ZXN0SG9vayB7XG4gICAgY29uc3RydWN0b3IgKHJlcXVlc3RGaWx0ZXJSdWxlSW5pdCwgb3B0aW9ucykge1xuICAgICAgICBvcHRpb25zID0gT2JqZWN0LmFzc2lnbih7fSwgREVGQVVMVF9PUFRJT05TLCBvcHRpb25zKTtcbiAgICAgICAgUmVxdWVzdExvZ2dlckltcGxlbWVudGF0aW9uLl9hc3NlcnRMb2dPcHRpb25zKG9wdGlvbnMpO1xuXG4gICAgICAgIGNvbnN0IGNvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zID0gbmV3IENvbmZpZ3VyZVJlc3BvbnNlRXZlbnRPcHRpb25zKG9wdGlvbnMubG9nUmVzcG9uc2VIZWFkZXJzLCBvcHRpb25zLmxvZ1Jlc3BvbnNlQm9keSk7XG5cbiAgICAgICAgc3VwZXIocmVxdWVzdEZpbHRlclJ1bGVJbml0LCBjb25maWd1cmVSZXNwb25zZUV2ZW50T3B0aW9ucyk7XG5cbiAgICAgICAgdGhpcy5vcHRpb25zID0gb3B0aW9ucztcblxuICAgICAgICB0aGlzLl9pbnRlcm5hbFJlcXVlc3RzID0ge307XG4gICAgfVxuXG4gICAgc3RhdGljIF9hc3NlcnRMb2dPcHRpb25zIChsb2dPcHRpb25zKSB7XG4gICAgICAgIGlmICghbG9nT3B0aW9ucy5sb2dSZXF1ZXN0Qm9keSAmJiBsb2dPcHRpb25zLnN0cmluZ2lmeVJlcXVlc3RCb2R5KVxuICAgICAgICAgICAgdGhyb3cgbmV3IEFQSUVycm9yKCdSZXF1ZXN0TG9nZ2VyJywgUlVOVElNRV9FUlJPUlMucmVxdWVzdEhvb2tDb25maWd1cmVBUElFcnJvciwgJ1JlcXVlc3RMb2dnZXInLCAnQ2Fubm90IHN0cmluZ2lmeSB0aGUgcmVxdWVzdCBib2R5IGJlY2F1c2UgaXQgaXMgbm90IGxvZ2dlZC4gU3BlY2lmeSB7IGxvZ1JlcXVlc3RCb2R5OiB0cnVlIH0gaW4gbG9nIG9wdGlvbnMuJyk7XG5cbiAgICAgICAgaWYgKCFsb2dPcHRpb25zLmxvZ1Jlc3BvbnNlQm9keSAmJiBsb2dPcHRpb25zLnN0cmluZ2lmeVJlc3BvbnNlQm9keSlcbiAgICAgICAgICAgIHRocm93IG5ldyBBUElFcnJvcignUmVxdWVzdExvZ2dlcicsIFJVTlRJTUVfRVJST1JTLnJlcXVlc3RIb29rQ29uZmlndXJlQVBJRXJyb3IsICdSZXF1ZXN0TG9nZ2VyJywgJ0Nhbm5vdCBzdHJpbmdpZnkgdGhlIHJlc3BvbnNlIGJvZHkgYmVjYXVzZSBpdCBpcyBub3QgbG9nZ2VkLiBTcGVjaWZ5IHsgbG9nUmVzcG9uc2VCb2R5OiB0cnVlIH0gaW4gbG9nIG9wdGlvbnMuJyk7XG4gICAgfVxuXG4gICAgYXN5bmMgb25SZXF1ZXN0IChldmVudCkge1xuICAgICAgICBjb25zdCB1c2VyQWdlbnQgPSBwYXJzZVVzZXJBZ2VudChldmVudC5fcmVxdWVzdEluZm8udXNlckFnZW50KS50b1N0cmluZygpO1xuXG4gICAgICAgIGNvbnN0IGxvZ2dlZFJlcSA9IHtcbiAgICAgICAgICAgIGlkOiAgICAgICAgZXZlbnQuX3JlcXVlc3RJbmZvLnJlcXVlc3RJZCxcbiAgICAgICAgICAgIHRlc3RSdW5JZDogZXZlbnQuX3JlcXVlc3RJbmZvLnNlc3Npb25JZCxcbiAgICAgICAgICAgIHVzZXJBZ2VudCxcbiAgICAgICAgICAgIHJlcXVlc3Q6ICAge1xuICAgICAgICAgICAgICAgIHVybDogICAgZXZlbnQuX3JlcXVlc3RJbmZvLnVybCxcbiAgICAgICAgICAgICAgICBtZXRob2Q6IGV2ZW50Ll9yZXF1ZXN0SW5mby5tZXRob2QsXG4gICAgICAgICAgICB9XG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sb2dSZXF1ZXN0SGVhZGVycylcbiAgICAgICAgICAgIGxvZ2dlZFJlcS5yZXF1ZXN0LmhlYWRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBldmVudC5fcmVxdWVzdEluZm8uaGVhZGVycyk7XG5cbiAgICAgICAgaWYgKHRoaXMub3B0aW9ucy5sb2dSZXF1ZXN0Qm9keSlcbiAgICAgICAgICAgIGxvZ2dlZFJlcS5yZXF1ZXN0LmJvZHkgPSB0aGlzLm9wdGlvbnMuc3RyaW5naWZ5UmVxdWVzdEJvZHkgPyBldmVudC5fcmVxdWVzdEluZm8uYm9keS50b1N0cmluZygpIDogZXZlbnQuX3JlcXVlc3RJbmZvLmJvZHk7XG5cbiAgICAgICAgdGhpcy5faW50ZXJuYWxSZXF1ZXN0c1tsb2dnZWRSZXEuaWRdID0gbG9nZ2VkUmVxO1xuICAgIH1cblxuICAgIGFzeW5jIG9uUmVzcG9uc2UgKGV2ZW50KSB7XG4gICAgICAgIGNvbnN0IGxvZ2dlclJlcSA9IHRoaXMuX2ludGVybmFsUmVxdWVzdHNbZXZlbnQucmVxdWVzdElkXTtcblxuICAgICAgICAvLyBOT1RFOiBJZiB0aGUgJ2NsZWFyJyBtZXRob2QgaXMgY2FsbGVkIGR1cmluZyBhIGxvbmcgcnVubmluZyByZXF1ZXN0LFxuICAgICAgICAvLyB3ZSBzaG91bGQgbm90IHNhdmUgYSByZXNwb25zZSBwYXJ0IC0gcmVxdWVzdCBwYXJ0IGhhcyBiZWVuIGFscmVhZHkgcmVtb3ZlZC5cbiAgICAgICAgaWYgKCFsb2dnZXJSZXEpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlICAgICAgICAgICAgPSB7fTtcbiAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlLnN0YXR1c0NvZGUgPSBldmVudC5zdGF0dXNDb2RlO1xuXG4gICAgICAgIGlmICh0aGlzLm9wdGlvbnMubG9nUmVzcG9uc2VIZWFkZXJzKVxuICAgICAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlLmhlYWRlcnMgPSBPYmplY3QuYXNzaWduKHt9LCBldmVudC5oZWFkZXJzKTtcblxuICAgICAgICBpZiAodGhpcy5vcHRpb25zLmxvZ1Jlc3BvbnNlQm9keSkge1xuICAgICAgICAgICAgbG9nZ2VyUmVxLnJlc3BvbnNlLmJvZHkgPSB0aGlzLm9wdGlvbnMuc3RyaW5naWZ5UmVzcG9uc2VCb2R5ICYmIGV2ZW50LmJvZHlcbiAgICAgICAgICAgICAgICA/IGV2ZW50LmJvZHkudG9TdHJpbmcoKVxuICAgICAgICAgICAgICAgIDogZXZlbnQuYm9keTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIF9wcmVwYXJlSW50ZXJuYWxSZXF1ZXN0SW5mbyAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW4gICAgICAgID0gdGVzdFJ1blRyYWNrZXIucmVzb2x2ZUNvbnRleHRUZXN0UnVuKCk7XG4gICAgICAgIGxldCBwcmVwYXJlZFJlcXVlc3RzID0gT2JqZWN0LnZhbHVlcyh0aGlzLl9pbnRlcm5hbFJlcXVlc3RzKTtcblxuICAgICAgICBpZiAodGVzdFJ1bilcbiAgICAgICAgICAgIHByZXBhcmVkUmVxdWVzdHMgPSBwcmVwYXJlZFJlcXVlc3RzLmZpbHRlcihyID0+IHIudGVzdFJ1bklkID09PSB0ZXN0UnVuLmlkKTtcblxuICAgICAgICByZXR1cm4gcHJlcGFyZWRSZXF1ZXN0cztcbiAgICB9XG5cbiAgICBfZ2V0Q29tcGxldGVkUmVxdWVzdHMgKCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fcHJlcGFyZUludGVybmFsUmVxdWVzdEluZm8oKS5maWx0ZXIociA9PiByLnJlc3BvbnNlKTtcbiAgICB9XG5cbiAgICAvLyBBUElcbiAgICBjb250YWlucyAocHJlZGljYXRlKSB7XG4gICAgICAgIHJldHVybiBSZUV4ZWN1dGFibGVQcm9taXNlLmZyb21Gbihhc3luYyAoKSA9PiB7XG4gICAgICAgICAgICByZXR1cm4gISF0aGlzLl9nZXRDb21wbGV0ZWRSZXF1ZXN0cygpLmZpbmQocHJlZGljYXRlKTtcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgY291bnQgKHByZWRpY2F0ZSkge1xuICAgICAgICByZXR1cm4gUmVFeGVjdXRhYmxlUHJvbWlzZS5mcm9tRm4oYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuX2dldENvbXBsZXRlZFJlcXVlc3RzKCkuZmlsdGVyKHByZWRpY2F0ZSkubGVuZ3RoO1xuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBjbGVhciAoKSB7XG4gICAgICAgIGNvbnN0IHRlc3RSdW4gPSB0ZXN0UnVuVHJhY2tlci5yZXNvbHZlQ29udGV4dFRlc3RSdW4oKTtcblxuICAgICAgICBpZiAodGVzdFJ1bikge1xuICAgICAgICAgICAgT2JqZWN0LmtleXModGhpcy5faW50ZXJuYWxSZXF1ZXN0cykuZm9yRWFjaChpZCA9PiB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX2ludGVybmFsUmVxdWVzdHNbaWRdLnRlc3RSdW5JZCA9PT0gdGVzdFJ1bi5pZClcbiAgICAgICAgICAgICAgICAgICAgZGVsZXRlIHRoaXMuX2ludGVybmFsUmVxdWVzdHNbaWRdO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgdGhpcy5faW50ZXJuYWxSZXF1ZXN0cyA9IHt9O1xuICAgIH1cblxuICAgIGdldCByZXF1ZXN0cyAoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9wcmVwYXJlSW50ZXJuYWxSZXF1ZXN0SW5mbygpO1xuICAgIH1cbn1cblxuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gY3JlYXRlUmVxdWVzdExvZ2dlciAocmVxdWVzdEZpbHRlclJ1bGVJbml0LCBsb2dPcHRpb25zKSB7XG4gICAgcmV0dXJuIG5ldyBSZXF1ZXN0TG9nZ2VySW1wbGVtZW50YXRpb24ocmVxdWVzdEZpbHRlclJ1bGVJbml0LCBsb2dPcHRpb25zKTtcbn1cblxuIl19