@browserstack/testcafe
Version:
Automated browser testing for the modern web development stack.
164 lines • 28.6 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable */
const read_file_relative_1 = require("read-file-relative");
const http_1 = require("../../utils/http");
const remotes_queue_1 = __importDefault(require("./remotes-queue"));
const IDLE_PAGE_SCRIPT = read_file_relative_1.readSync('../../client/browser/idle-page/index.js');
const IDLE_PAGE_STYLE = read_file_relative_1.readSync('../../client/browser/idle-page/styles.css');
const IDLE_PAGE_LOGO = read_file_relative_1.readSync('../../client/browser/idle-page/logo.svg', true);
class BrowserConnectionGateway {
constructor(proxy, options) {
this._connections = {};
this._remotesQueue = new remotes_queue_1.default();
// @ts-ignore Need to improve typings of the 'testcafe-hammerhead' module
this.domain = proxy.server1Info.domain;
this.connectUrl = `${this.domain}/browser/connect`;
this.retryTestPages = options.retryTestPages;
this._registerRoutes(proxy);
}
_dispatch(url, proxy, handler, method = 'GET') {
// @ts-ignore Need to improve typings of the 'testcafe-hammerhead' module
proxy[method](url, (req, res, serverInfo, params) => {
const connection = this._connections[params.id];
http_1.preventCaching(res);
if (connection)
handler(req, res, connection);
else {
// console.log(`Sending 404 for this ${url}`);
http_1.respond404(res);
}
});
}
_registerRoutes(proxy) {
this._dispatch('/browser/connect/{id}', proxy, BrowserConnectionGateway._onConnection);
this._dispatch('/browser/heartbeat/{id}', proxy, BrowserConnectionGateway._onHeartbeat);
this._dispatch('/browser/idle/{id}', proxy, BrowserConnectionGateway._onIdle);
this._dispatch('/browser/idle-forced/{id}', proxy, BrowserConnectionGateway._onIdleForced);
this._dispatch('/browser/status/{id}', proxy, BrowserConnectionGateway._onStatusRequest);
this._dispatch('/browser/status-done/{id}', proxy, BrowserConnectionGateway._onStatusRequestOnTestDone);
this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway._onInitScriptRequest);
this._dispatch('/browser/init-script/{id}', proxy, BrowserConnectionGateway._onInitScriptResponse, 'POST');
this._dispatch('/browser/active-window-id/{id}', proxy, BrowserConnectionGateway._onGetActiveWindowIdRequest);
this._dispatch('/browser/active-window-id/{id}', proxy, BrowserConnectionGateway._onSetActiveWindowIdRequest, 'POST');
proxy.GET('/browser/connect', (req, res) => this._connectNextRemoteBrowser(req, res));
proxy.GET('/browser/connect/', (req, res) => this._connectNextRemoteBrowser(req, res));
proxy.GET('/browser/assets/index.js', { content: IDLE_PAGE_SCRIPT, contentType: 'application/x-javascript' });
proxy.GET('/browser/assets/styles.css', { content: IDLE_PAGE_STYLE, contentType: 'text/css' });
proxy.GET('/browser/assets/logo.svg', { content: IDLE_PAGE_LOGO, contentType: 'image/svg+xml' });
}
// Helpers
static _ensureConnectionReady(res, connection) {
if (!connection.isReady()) {
http_1.respond500(res, 'The connection is not ready yet.');
return false;
}
return true;
}
static _fetchRequestData(req, callback) {
let data = '';
req.on('data', chunk => {
data += chunk;
});
req.on('end', () => {
callback(data.toString());
});
}
// Route handlers
static _onConnection(req, res, connection) {
if (connection.isReady())
http_1.respond500(res, 'The connection is already established.');
else {
const userAgent = req.headers['user-agent'];
connection.establish(userAgent);
http_1.redirect(res, connection.idleUrl);
}
}
static _onHeartbeat(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
const status = connection.heartbeat();
http_1.respondWithJSON(res, status);
}
}
static _onIdle(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection))
res.end(connection.renderIdlePage());
}
static async _onIdleForced(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
const status = await connection.getStatus(true);
http_1.redirect(res, status.url);
}
}
static async _onStatusRequest(req, res, connection) {
return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, false);
}
static async _onStatusRequestOnTestDone(req, res, connection) {
return BrowserConnectionGateway._onStatusRequestCore(req, res, connection, true);
}
static async _onStatusRequestCore(req, res, connection, isTestDone) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
// console.log(`Asked from status request isTestDone: ${isTestDone}`);
const status = await connection.getStatus(isTestDone);
http_1.respondWithJSON(res, status);
}
}
static _onInitScriptRequest(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
const script = connection.getInitScript();
http_1.respondWithJSON(res, script);
}
}
static _onInitScriptResponse(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
BrowserConnectionGateway._fetchRequestData(req, data => {
connection.handleInitScriptResult(data);
res.end();
});
}
}
static _onGetActiveWindowIdRequest(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
http_1.respondWithJSON(res, {
activeWindowId: connection.activeWindowId
});
}
}
static _onSetActiveWindowIdRequest(req, res, connection) {
if (BrowserConnectionGateway._ensureConnectionReady(res, connection)) {
BrowserConnectionGateway._fetchRequestData(req, data => {
const parsedData = JSON.parse(data);
connection.activeWindowId = parsedData.windowId;
http_1.respondWithJSON(res);
});
}
}
async _connectNextRemoteBrowser(req, res) {
http_1.preventCaching(res);
const remoteConnection = await this._remotesQueue.shift();
if (remoteConnection)
http_1.redirect(res, remoteConnection.url);
else
http_1.respond500(res, 'There are no available _connections to establish.');
}
// API
startServingConnection(connection) {
this._connections[connection.id] = connection;
if (connection.browserInfo.providerName === 'remote')
this._remotesQueue.add(connection);
}
stopServingConnection(connection) {
delete this._connections[connection.id];
if (connection.browserInfo.providerName === 'remote')
this._remotesQueue.remove(connection);
}
close() {
Object.keys(this._connections).forEach(id => this._connections[id].close());
}
}
exports.default = BrowserConnectionGateway;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZ2F0ZXdheS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9icm93c2VyL2Nvbm5lY3Rpb24vZ2F0ZXdheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQUFBLG9CQUFvQjtBQUNwQiwyREFBc0Q7QUFDdEQsMkNBQXFHO0FBQ3JHLG9FQUEyQztBQU0zQyxNQUFNLGdCQUFnQixHQUFHLDZCQUFJLENBQUMseUNBQXlDLENBQUMsQ0FBQztBQUN6RSxNQUFNLGVBQWUsR0FBSSw2QkFBSSxDQUFDLDJDQUEyQyxDQUFDLENBQUM7QUFDM0UsTUFBTSxjQUFjLEdBQUssNkJBQUksQ0FBQyx5Q0FBeUMsRUFBRSxJQUFJLENBQUMsQ0FBQztBQUUvRSxNQUFxQix3QkFBd0I7SUFPekMsWUFBb0IsS0FBWSxFQUFFLE9BQW9DO1FBTjlELGlCQUFZLEdBQWtDLEVBQUUsQ0FBQztRQU9yRCxJQUFJLENBQUMsYUFBYSxHQUFLLElBQUksdUJBQVksRUFBRSxDQUFDO1FBQzFDLHlFQUF5RTtRQUN6RSxJQUFJLENBQUMsTUFBTSxHQUFhLEtBQWEsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDO1FBQ3pELElBQUksQ0FBQyxVQUFVLEdBQVEsR0FBRyxJQUFJLENBQUMsTUFBTSxrQkFBa0IsQ0FBQztRQUN4RCxJQUFJLENBQUMsY0FBYyxHQUFJLE9BQU8sQ0FBQyxjQUFjLENBQUM7UUFFOUMsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRU8sU0FBUyxDQUFFLEdBQVcsRUFBRSxLQUFZLEVBQUUsT0FBaUIsRUFBRSxNQUFNLEdBQUcsS0FBSztRQUMzRSx5RUFBeUU7UUFDekUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLEdBQW9CLEVBQUUsR0FBbUIsRUFBRSxVQUFVLEVBQUUsTUFBMEIsRUFBRSxFQUFFO1lBQ3JHLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMs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QUUsQ0FBQyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDaEYsQ0FBQztDQUNKO0FBak1ELDJDQWlNQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIGVzbGludC1kaXNhYmxlICovXG5pbXBvcnQgeyByZWFkU3luYyBhcyByZWFkIH0gZnJvbSAncmVhZC1maWxlLXJlbGF0aXZlJztcbmltcG9ydCB7IHJlc3BvbmQ0MDQsIHJlc3BvbmQ1MDAsIHJlc3BvbmRXaXRoSlNPTiwgcmVkaXJlY3QsIHByZXZlbnRDYWNoaW5nIH0gZnJvbSAnLi4vLi4vdXRpbHMvaHR0cCc7XG5pbXBvcnQgUmVtb3Rlc1F1ZXVlIGZyb20gJy4vcmVtb3Rlcy1xdWV1ZSc7XG5pbXBvcnQgeyBQcm94eSB9IGZyb20gJ3Rlc3RjYWZlLWhhbW1lcmhlYWQnO1xuaW1wb3J0IHsgRGljdGlvbmFyeSB9IGZyb20gJy4uLy4uL2NvbmZpZ3VyYXRpb24vaW50ZXJmYWNlcyc7XG5pbXBvcnQgQnJvd3NlckNvbm5lY3Rpb24gZnJvbSAnLi9pbmRleCc7XG5pbXBvcnQgeyBJbmNvbWluZ01lc3NhZ2UsIFNlcnZlclJlc3BvbnNlIH0gZnJvbSAnaHR0cCc7XG5cbmNvbnN0IElETEVfUEFHRV9TQ1JJUFQgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2UvaW5kZXguanMnKTtcbmNvbnN0IElETEVfUEFHRV9TVFlMRSAgPSByZWFkKCcuLi8uLi9jbGllbnQvYnJvd3Nlci9pZGxlLXBhZ2Uvc3R5bGVzLmNzcycpO1xuY29uc3QgSURMRV9QQUdFX0xPR08gICA9IHJlYWQoJy4uLy4uL2NsaWVudC9icm93c2VyL2lkbGUtcGFnZS9sb2dvLnN2ZycsIHRydWUpO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkge1xuICAgIHByaXZhdGUgX2Nvbm5lY3Rpb25zOiBEaWN0aW9uYXJ5PEJyb3dzZXJDb25uZWN0aW9uPiA9IHt9O1xuICAgIHByaXZhdGUgX3JlbW90ZXNRdWV1ZTogUmVtb3Rlc1F1ZXVlO1xuICAgIHB1YmxpYyByZWFkb25seSBkb21haW46IHN0cmluZztcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29ubmVjdFVybDogc3RyaW5nO1xuICAgIHB1YmxpYyByZXRyeVRlc3RQYWdlczogYm9vbGVhbjtcblxuICAgIHB1YmxpYyBjb25zdHJ1Y3RvciAocHJveHk6IFByb3h5LCBvcHRpb25zOiB7IHJldHJ5VGVzdFBhZ2VzOiBib29sZWFuIH0pIHtcbiAgICAgICAgdGhpcy5fcmVtb3Rlc1F1ZXVlICAgPSBuZXcgUmVtb3Rlc1F1ZXVlKCk7XG4gICAgICAgIC8vIEB0cy1pZ25vcmUgTmVlZCB0byBpbXByb3ZlIHR5cGluZ3Mgb2YgdGhlICd0ZXN0Y2FmZS1oYW1tZXJoZWFkJyBtb2R1bGVcbiAgICAgICAgdGhpcy5kb21haW4gICAgICAgICAgPSAocHJveHkgYXMgYW55KS5zZXJ2ZXIxSW5mby5kb21haW47XG4gICAgICAgIHRoaXMuY29ubmVjdFVybCAgICAgID0gYCR7dGhpcy5kb21haW59L2Jyb3dzZXIvY29ubmVjdGA7XG4gICAgICAgIHRoaXMucmV0cnlUZXN0UGFnZXMgID0gb3B0aW9ucy5yZXRyeVRlc3RQYWdlcztcblxuICAgICAgICB0aGlzLl9yZWdpc3RlclJvdXRlcyhwcm94eSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZGlzcGF0Y2ggKHVybDogc3RyaW5nLCBwcm94eTogUHJveHksIGhhbmRsZXI6IEZ1bmN0aW9uLCBtZXRob2QgPSAnR0VUJyk6IHZvaWQge1xuICAgICAgICAvLyBAdHMtaWdub3JlIE5lZWQgdG8gaW1wcm92ZSB0eXBpbmdzIG9mIHRoZSAndGVzdGNhZmUtaGFtbWVyaGVhZCcgbW9kdWxlXG4gICAgICAgIHByb3h5W21ldGhvZF0odXJsLCAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIHNlcnZlckluZm8sIHBhcmFtczogRGljdGlvbmFyeTxzdHJpbmc+KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5fY29ubmVjdGlvbnNbcGFyYW1zLmlkXTtcblxuICAgICAgICAgICAgcHJldmVudENhY2hpbmcocmVzKTtcblxuICAgICAgICAgICAgaWYgKGNvbm5lY3Rpb24pXG4gICAgICAgICAgICAgICAgaGFuZGxlcihyZXEsIHJlcywgY29ubmVjdGlvbik7XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgU2VuZGluZyA0MDQgZm9yIHRoaXMgJHt1cmx9YCk7XG4gICAgICAgICAgICAgICAgcmVzcG9uZDQwNChyZXMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIF9yZWdpc3RlclJvdXRlcyAocHJveHk6IFByb3h5KTogdm9pZCB7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9jb25uZWN0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vbkNvbm5lY3Rpb24pO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaGVhcnRiZWF0L3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vbkhlYXJ0YmVhdCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pZGxlL3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vbklkbGUpO1xuICAgICAgICB0aGlzLl9kaXNwYXRjaCgnL2Jyb3dzZXIvaWRsZS1mb3JjZWQve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX29uSWRsZUZvcmNlZCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9zdGF0dXMve2lkfScsIHByb3h5LCBCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX29uU3RhdHVzUmVxdWVzdCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9zdGF0dXMtZG9uZS97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fb25TdGF0dXNSZXF1ZXN0T25UZXN0RG9uZSk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pbml0LXNjcmlwdC97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fb25Jbml0U2NyaXB0UmVxdWVzdCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9pbml0LXNjcmlwdC97aWR9JywgcHJveHksIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fb25Jbml0U2NyaXB0UmVzcG9uc2UsICdQT1NUJyk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9hY3RpdmUtd2luZG93LWlkL3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vbkdldEFjdGl2ZVdpbmRvd0lkUmVxdWVzdCk7XG4gICAgICAgIHRoaXMuX2Rpc3BhdGNoKCcvYnJvd3Nlci9hY3RpdmUtd2luZG93LWlkL3tpZH0nLCBwcm94eSwgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vblNldEFjdGl2ZVdpbmRvd0lkUmVxdWVzdCwgJ1BPU1QnKTtcblxuICAgICAgICBwcm94eS5HRVQoJy9icm93c2VyL2Nvbm5lY3QnLCAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UpID0+IHRoaXMuX2Nvbm5lY3ROZXh0UmVtb3RlQnJvd3NlcihyZXEsIHJlcykpO1xuICAgICAgICBwcm94eS5HRVQoJy9icm93c2VyL2Nvbm5lY3QvJywgKHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlKSA9PiB0aGlzLl9jb25uZWN0TmV4dFJlbW90ZUJyb3dzZXIocmVxLCByZXMpKTtcblxuICAgICAgICBwcm94eS5HRVQoJy9icm93c2VyL2Fzc2V0cy9pbmRleC5qcycsIHsgY29udGVudDogSURMRV9QQUdFX1NDUklQVCwgY29udGVudFR5cGU6ICdhcHBsaWNhdGlvbi94LWphdmFzY3JpcHQnIH0pO1xuICAgICAgICBwcm94eS5HRVQoJy9icm93c2VyL2Fzc2V0cy9zdHlsZXMuY3NzJywgeyBjb250ZW50OiBJRExFX1BBR0VfU1RZTEUsIGNvbnRlbnRUeXBlOiAndGV4dC9jc3MnIH0pO1xuICAgICAgICBwcm94eS5HRVQoJy9icm93c2VyL2Fzc2V0cy9sb2dvLnN2ZycsIHsgY29udGVudDogSURMRV9QQUdFX0xPR08sIGNvbnRlbnRUeXBlOiAnaW1hZ2Uvc3ZnK3htbCcgfSk7XG4gICAgfVxuXG4gICAgLy8gSGVscGVyc1xuICAgIHByaXZhdGUgc3RhdGljIF9lbnN1cmVDb25uZWN0aW9uUmVhZHkgKHJlczogU2VydmVyUmVzcG9uc2UsIGNvbm5lY3Rpb246IEJyb3dzZXJDb25uZWN0aW9uKTogYm9vbGVhbiB7XG4gICAgICAgIGlmICghY29ubmVjdGlvbi5pc1JlYWR5KCkpIHtcbiAgICAgICAgICAgIHJlc3BvbmQ1MDAocmVzLCAnVGhlIGNvbm5lY3Rpb24gaXMgbm90IHJlYWR5IHlldC4nKTtcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIF9mZXRjaFJlcXVlc3REYXRhIChyZXE6IEluY29taW5nTWVzc2FnZSwgY2FsbGJhY2s6IChkYXRhOiBzdHJpbmcpID0+IHZvaWQpOiB2b2lkIHtcbiAgICAgICAgbGV0IGRhdGEgPSAnJztcblxuICAgICAgICByZXEub24oJ2RhdGEnLCBjaHVuayA9PiB7XG4gICAgICAgICAgICBkYXRhICs9IGNodW5rO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXEub24oJ2VuZCcsICgpID0+IHtcbiAgICAgICAgICAgIGNhbGxiYWNrKGRhdGEudG9TdHJpbmcoKSk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIFJvdXRlIGhhbmRsZXJzXG4gICAgcHJpdmF0ZSBzdGF0aWMgX29uQ29ubmVjdGlvbiAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIGNvbm5lY3Rpb246IEJyb3dzZXJDb25uZWN0aW9uKTogdm9pZCB7XG4gICAgICAgIGlmIChjb25uZWN0aW9uLmlzUmVhZHkoKSlcbiAgICAgICAgICAgIHJlc3BvbmQ1MDAocmVzLCAnVGhlIGNvbm5lY3Rpb24gaXMgYWxyZWFkeSBlc3RhYmxpc2hlZC4nKTtcblxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHVzZXJBZ2VudCA9IHJlcS5oZWFkZXJzWyd1c2VyLWFnZW50J10gYXMgc3RyaW5nO1xuXG4gICAgICAgICAgICBjb25uZWN0aW9uLmVzdGFibGlzaCh1c2VyQWdlbnQpO1xuICAgICAgICAgICAgcmVkaXJlY3QocmVzLCBjb25uZWN0aW9uLmlkbGVVcmwpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX29uSGVhcnRiZWF0IChyZXE6IEluY29taW5nTWVzc2FnZSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSwgY29ubmVjdGlvbjogQnJvd3NlckNvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGNvbnN0IHN0YXR1cyA9IGNvbm5lY3Rpb24uaGVhcnRiZWF0KCk7XG5cbiAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMsIHN0YXR1cyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfb25JZGxlIChyZXE6IEluY29taW5nTWVzc2FnZSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSwgY29ubmVjdGlvbjogQnJvd3NlckNvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpXG4gICAgICAgICAgICByZXMuZW5kKGNvbm5lY3Rpb24ucmVuZGVySWRsZVBhZ2UoKSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgX29uSWRsZUZvcmNlZCAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIGNvbm5lY3Rpb246IEJyb3dzZXJDb25uZWN0aW9uKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX2Vuc3VyZUNvbm5lY3Rpb25SZWFkeShyZXMsIGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBjb25uZWN0aW9uLmdldFN0YXR1cyh0cnVlKTtcblxuICAgICAgICAgICAgcmVkaXJlY3QocmVzLCBzdGF0dXMudXJsKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIGFzeW5jIF9vblN0YXR1c1JlcXVlc3QgKHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlLCBjb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vblN0YXR1c1JlcXVlc3RDb3JlKHJlcSwgcmVzLCBjb25uZWN0aW9uLCBmYWxzZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgYXN5bmMgX29uU3RhdHVzUmVxdWVzdE9uVGVzdERvbmUgKHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlLCBjb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbik6IFByb21pc2U8dm9pZD4ge1xuICAgICAgICByZXR1cm4gQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9vblN0YXR1c1JlcXVlc3RDb3JlKHJlcSwgcmVzLCBjb25uZWN0aW9uLCB0cnVlKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBhc3luYyBfb25TdGF0dXNSZXF1ZXN0Q29yZSAocmVxOiBJbmNvbWluZ01lc3NhZ2UsIHJlczogU2VydmVyUmVzcG9uc2UsIGNvbm5lY3Rpb246IEJyb3dzZXJDb25uZWN0aW9uLCBpc1Rlc3REb25lOiBib29sZWFuKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIGlmIChCcm93c2VyQ29ubmVjdGlvbkdhdGV3YXkuX2Vuc3VyZUNvbm5lY3Rpb25SZWFkeShyZXMsIGNvbm5lY3Rpb24pKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgQXNrZWQgZnJvbSBzdGF0dXMgcmVxdWVzdCBpc1Rlc3REb25lOiAke2lzVGVzdERvbmV9YCk7XG4gICAgICAgICAgICBjb25zdCBzdGF0dXMgPSBhd2FpdCBjb25uZWN0aW9uLmdldFN0YXR1cyhpc1Rlc3REb25lKTtcblxuICAgICAgICAgICAgcmVzcG9uZFdpdGhKU09OKHJlcywgc3RhdHVzKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgc3RhdGljIF9vbkluaXRTY3JpcHRSZXF1ZXN0IChyZXE6IEluY29taW5nTWVzc2FnZSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSwgY29ubmVjdGlvbjogQnJvd3NlckNvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIGNvbnN0IHNjcmlwdCA9IGNvbm5lY3Rpb24uZ2V0SW5pdFNjcmlwdCgpO1xuXG4gICAgICAgICAgICByZXNwb25kV2l0aEpTT04ocmVzLCBzY3JpcHQpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX29uSW5pdFNjcmlwdFJlc3BvbnNlIChyZXE6IEluY29taW5nTWVzc2FnZSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSwgY29ubmVjdGlvbjogQnJvd3NlckNvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fZmV0Y2hSZXF1ZXN0RGF0YShyZXEsIGRhdGEgPT4ge1xuICAgICAgICAgICAgICAgIGNvbm5lY3Rpb24uaGFuZGxlSW5pdFNjcmlwdFJlc3VsdChkYXRhKTtcblxuICAgICAgICAgICAgICAgIHJlcy5lbmQoKTtcbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBzdGF0aWMgX29uR2V0QWN0aXZlV2luZG93SWRSZXF1ZXN0IChyZXE6IEluY29taW5nTWVzc2FnZSwgcmVzOiBTZXJ2ZXJSZXNwb25zZSwgY29ubmVjdGlvbjogQnJvd3NlckNvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgaWYgKEJyb3dzZXJDb25uZWN0aW9uR2F0ZXdheS5fZW5zdXJlQ29ubmVjdGlvblJlYWR5KHJlcywgY29ubmVjdGlvbikpIHtcbiAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMsIHtcbiAgICAgICAgICAgICAgICBhY3RpdmVXaW5kb3dJZDogY29ubmVjdGlvbi5hY3RpdmVXaW5kb3dJZFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIHN0YXRpYyBfb25TZXRBY3RpdmVXaW5kb3dJZFJlcXVlc3QgKHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlLCBjb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbik6IHZvaWQge1xuICAgICAgICBpZiAoQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9lbnN1cmVDb25uZWN0aW9uUmVhZHkocmVzLCBjb25uZWN0aW9uKSkge1xuICAgICAgICAgICAgQnJvd3NlckNvbm5lY3Rpb25HYXRld2F5Ll9mZXRjaFJlcXVlc3REYXRhKHJlcSwgZGF0YSA9PiB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoZGF0YSk7XG5cbiAgICAgICAgICAgICAgICBjb25uZWN0aW9uLmFjdGl2ZVdpbmRvd0lkID0gcGFyc2VkRGF0YS53aW5kb3dJZDtcblxuICAgICAgICAgICAgICAgIHJlc3BvbmRXaXRoSlNPTihyZXMpO1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwcml2YXRlIGFzeW5jIF9jb25uZWN0TmV4dFJlbW90ZUJyb3dzZXIgKHJlcTogSW5jb21pbmdNZXNzYWdlLCByZXM6IFNlcnZlclJlc3BvbnNlKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgICAgIHByZXZlbnRDYWNoaW5nKHJlcyk7XG5cbiAgICAgICAgY29uc3QgcmVtb3RlQ29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuX3JlbW90ZXNRdWV1ZS5zaGlmdCgpO1xuXG4gICAgICAgIGlmIChyZW1vdGVDb25uZWN0aW9uKVxuICAgICAgICAgICAgcmVkaXJlY3QocmVzLCByZW1vdGVDb25uZWN0aW9uLnVybCk7XG4gICAgICAgIGVsc2VcbiAgICAgICAgICAgIHJlc3BvbmQ1MDAocmVzLCAnVGhlcmUgYXJlIG5vIGF2YWlsYWJsZSBfY29ubmVjdGlvbnMgdG8gZXN0YWJsaXNoLicpO1xuICAgIH1cblxuICAgIC8vIEFQSVxuICAgIHB1YmxpYyBzdGFydFNlcnZpbmdDb25uZWN0aW9uIChjb25uZWN0aW9uOiBCcm93c2VyQ29ubmVjdGlvbik6IHZvaWQge1xuICAgICAgICB0aGlzLl9jb25uZWN0aW9uc1tjb25uZWN0aW9uLmlkXSA9IGNvbm5lY3Rpb247XG5cbiAgICAgICAgaWYgKGNvbm5lY3Rpb24uYnJvd3NlckluZm8ucHJvdmlkZXJOYW1lID09PSAncmVtb3RlJylcbiAgICAgICAgICAgIHRoaXMuX3JlbW90ZXNRdWV1ZS5hZGQoY29ubmVjdGlvbik7XG4gICAgfVxuXG4gICAgcHVibGljIHN0b3BTZXJ2aW5nQ29ubmVjdGlvbiAoY29ubmVjdGlvbjogQnJvd3NlckNvbm5lY3Rpb24pOiB2b2lkIHtcbiAgICAgICAgZGVsZXRlIHRoaXMuX2Nvbm5lY3Rpb25zW2Nvbm5lY3Rpb24uaWRdO1xuXG4gICAgICAgIGlmIChjb25uZWN0aW9uLmJyb3dzZXJJbmZvLnByb3ZpZGVyTmFtZSA9PT0gJ3JlbW90ZScpXG4gICAgICAgICAgICB0aGlzLl9yZW1vdGVzUXVldWUucmVtb3ZlKGNvbm5lY3Rpb24pO1xuICAgIH1cblxuICAgIHB1YmxpYyBjbG9zZSAoKTogdm9pZCB7XG4gICAgICAgIE9iamVjdC5rZXlzKHRoaXMuX2Nvbm5lY3Rpb25zKS5mb3JFYWNoKGlkID0+IHRoaXMuX2Nvbm5lY3Rpb25zW2lkXS5jbG9zZSgpKTtcbiAgICB9XG59XG5cbiJdfQ==