@browserstack/testcafe
Version:
Automated browser testing for the modern web development stack.
131 lines • 21.8 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const path_1 = __importDefault(require("path"));
const os_1 = __importDefault(require("os"));
const chrome_remote_interface_1 = __importDefault(require("chrome-remote-interface"));
const client_functions_1 = require("../../../utils/client-functions");
const DOWNLOADS_DIR = path_1.default.join(os_1.default.homedir(), 'Downloads');
async function getActiveTab(cdpPort, browserId) {
const tabs = await chrome_remote_interface_1.default.listTabs({ port: cdpPort });
return tabs.filter(t => t.type === 'page' && t.url.includes(browserId))[0];
}
async function setEmulationBounds({ client, config, viewportSize, emulatedDevicePixelRatio }) {
await setDeviceMetricsOverride(client, viewportSize.width, viewportSize.height, emulatedDevicePixelRatio, config.mobile);
await client.Emulation.setVisibleSize({ width: viewportSize.width, height: viewportSize.height });
}
async function setEmulation(runtimeInfo) {
const { client, config } = runtimeInfo;
if (config.userAgent !== void 0)
await client.Network.setUserAgentOverride({ userAgent: config.userAgent });
if (config.touch !== void 0) {
const touchConfig = {
enabled: config.touch,
configuration: config.mobile ? 'mobile' : 'desktop',
maxTouchPoints: 1
};
if (client.Emulation.setEmitTouchEventsForMouse)
await client.Emulation.setEmitTouchEventsForMouse(touchConfig);
if (client.Emulation.setTouchEmulationEnabled)
await client.Emulation.setTouchEmulationEnabled(touchConfig);
}
await resizeWindow({ width: config.width, height: config.height }, runtimeInfo);
}
async function enableDownloads({ client }) {
await client.Page.setDownloadBehavior({
behavior: 'allow',
downloadPath: DOWNLOADS_DIR
});
}
async function getScreenshotData({ client, config, emulatedDevicePixelRatio }, fullPage) {
let viewportWidth = 0;
let viewportHeight = 0;
if (fullPage) {
const { contentSize, visualViewport } = await client.Page.getLayoutMetrics();
await setDeviceMetricsOverride(client, Math.ceil(contentSize.width), Math.ceil(contentSize.height), emulatedDevicePixelRatio, config.mobile);
viewportWidth = visualViewport.clientWidth;
viewportHeight = visualViewport.clientHeight;
}
const screenshotData = await client.Page.captureScreenshot({});
if (fullPage) {
if (config.emulation) {
await setDeviceMetricsOverride(client, config.width || viewportWidth, config.height || viewportHeight, emulatedDevicePixelRatio, config.mobile);
}
else
await client.Emulation.clearDeviceMetricsOverride();
}
return Buffer.from(screenshotData.data, 'base64');
}
exports.getScreenshotData = getScreenshotData;
async function setDeviceMetricsOverride(client, width, height, deviceScaleFactor, mobile) {
await client.Emulation.setDeviceMetricsOverride({
width,
height,
deviceScaleFactor,
mobile,
// @ts-ignore
fitWindow: false
});
}
async function createClient(runtimeInfo) {
const { browserId, config, cdpPort } = runtimeInfo;
let tab = null;
let client = null;
try {
tab = await getActiveTab(cdpPort, browserId);
if (!tab)
return;
client = await chrome_remote_interface_1.default({ target: tab, port: cdpPort });
}
catch (e) {
return;
}
runtimeInfo.tab = tab;
runtimeInfo.client = client;
await client.Page.enable();
await client.Network.enable({});
await client.Runtime.enable();
const devicePixelRatioQueryResult = await client.Runtime.evaluate({ expression: 'window.devicePixelRatio' });
runtimeInfo.originalDevicePixelRatio = devicePixelRatioQueryResult.result.value;
runtimeInfo.emulatedDevicePixelRatio = config.scaleFactor || runtimeInfo.originalDevicePixelRatio;
if (config.emulation)
await setEmulation(runtimeInfo);
if (config.headless)
await enableDownloads(runtimeInfo);
}
exports.createClient = createClient;
function isHeadlessTab({ tab, config }) {
return tab && config.headless;
}
exports.isHeadlessTab = isHeadlessTab;
async function closeTab({ tab, cdpPort }) {
await chrome_remote_interface_1.default.closeTab({ id: tab.id, port: cdpPort });
}
exports.closeTab = closeTab;
async function updateMobileViewportSize(runtimeInfo) {
const windowDimensionsQueryResult = await runtimeInfo.client.Runtime.evaluate({
expression: `(${client_functions_1.GET_WINDOW_DIMENSIONS_INFO_SCRIPT})()`,
returnByValue: true
});
const windowDimensions = windowDimensionsQueryResult.result.value;
runtimeInfo.viewportSize.width = windowDimensions.outerWidth;
runtimeInfo.viewportSize.height = windowDimensions.outerHeight;
}
exports.updateMobileViewportSize = updateMobileViewportSize;
async function resizeWindow(newDimensions, runtimeInfo) {
const { browserId, config, viewportSize, providerMethods } = runtimeInfo;
const currentWidth = viewportSize.width;
const currentHeight = viewportSize.height;
const newWidth = newDimensions.width || currentWidth;
const newHeight = newDimensions.height || currentHeight;
if (!config.headless)
await providerMethods.resizeLocalBrowserWindow(browserId, newWidth, newHeight, currentWidth, currentHeight);
viewportSize.width = newWidth;
viewportSize.height = newHeight;
if (config.emulation)
await setEmulationBounds(runtimeInfo);
}
exports.resizeWindow = resizeWindow;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2Jyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vZGVkaWNhdGVkL2Nocm9tZS9jZHAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxnREFBd0I7QUFDeEIsNENBQW9CO0FBQ3BCLHNGQUFtRDtBQUNuRCxzRUFBb0Y7QUF3Q3BGLE1BQU0sYUFBYSxHQUFHLGNBQUksQ0FBQyxJQUFJLENBQUMsWUFBRSxDQUFDLE9BQU8sRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0FBRTNELEtBQUssVUFBVSxZQUFZLENBQUUsT0FBZSxFQUFFLFNBQWlCO0lBQzNELE1BQU0sSUFBSSxHQUFHLE1BQU0saUNBQVksQ0FBQyxRQUFRLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQztJQUU1RCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQy9FLENBQUM7QUFFRCxLQUFLLFVBQVUsa0JBQWtCLENBQUUsRUFBRSxNQUFNLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSx3QkFBd0IsRUFBZTtJQUN0RyxNQUFNLHdCQUF3QixDQUFDLE1BQU0sRUFBRSxZQUFZLENBQUMsS0FBSyxFQUFFLFlBQVksQ0FBQyxNQUFNLEVBQUUsd0JBQXdCLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBRXpILE1BQU0sTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsRUFBRSxLQUFLLEVBQUUsWUFBWSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUM7QUFDdEcsQ0FBQztBQUVELEtBQUssVUFBVSxZ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RSxhQUFtQixFQUFFLFdBQXdCO0lBQzdFLE1BQU0sRUFBRSxTQUFTLEVBQUUsTUFBTSxFQUFFLFlBQVksRUFBRSxlQUFlLEVBQUUsR0FBRyxXQUFXLENBQUM7SUFFekUsTUFBTSxZQUFZLEdBQUksWUFBWSxDQUFDLEtBQUssQ0FBQztJQUN6QyxNQUFNLGFBQWEsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDO0lBQzFDLE1BQU0sUUFBUSxHQUFRLGFBQWEsQ0FBQyxLQUFLLElBQUksWUFBWSxDQUFDO0lBQzFELE1BQU0sU0FBUyxHQUFPLGFBQWEsQ0FBQyxNQUFNLElBQUksYUFBYSxDQUFDO0lBRTVELElBQUksQ0FBQyxNQUFNLENBQUMsUUFBUTtRQUNoQixNQUFNLGVBQWUsQ0FBQyx3QkFBd0IsQ0FBQyxTQUFTLEVBQUUsUUFBUSxFQUFFLFNBQVMsRUFBRSxZQUFZLEVBQUUsYUFBYSxDQUFDLENBQUM7SUFFaEgsWUFBWSxDQUFDLEtBQUssR0FBSSxRQUFRLENBQUM7SUFDL0IsWUFBWSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFFaEMsSUFBSSxNQUFNLENBQUMsU0FBUztRQUNoQixNQUFNLGtCQUFrQixDQUFDLFdBQVcsQ0FBQyxDQUFDO0FBQzlDLENBQUM7QUFoQkQsb0NBZ0JDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgb3MgZnJvbSAnb3MnO1xuaW1wb3J0IHJlbW90ZUNocm9tZSBmcm9tICdjaHJvbWUtcmVtb3RlLWludGVyZmFjZSc7XG5pbXBvcnQgeyBHRVRfV0lORE9XX0RJTUVOU0lPTlNfSU5GT19TQ1JJUFQgfSBmcm9tICcuLi8uLi8uLi91dGlscy9jbGllbnQtZnVuY3Rpb25zJztcblxuaW50ZXJmYWNlIFNpemUge1xuICAgIHdpZHRoOiBudW1iZXI7XG4gICAgaGVpZ2h0OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBDb25maWcge1xuICAgIGhlYWRsZXNzOiBib29sZWFuO1xuICAgIG1vYmlsZTogYm9vbGVhbjtcbiAgICBlbXVsYXRpb246IGZhbHNlO1xuICAgIHVzZXJBZ2VudD86IHN0cmluZztcbiAgICB0b3VjaD86IGJvb2xlYW47XG4gICAgd2lkdGg6IG51bWJlcjtcbiAgICBoZWlnaHQ6IG51bWJlcjtcbiAgICBzY2FsZUZhY3RvcjogbnVtYmVyO1xufVxuXG5pbnRlcmZhY2UgUHJvdmlkZXJNZXRob2RzIHtcbiAgICByZXNpemVMb2NhbEJyb3dzZXJXaW5kb3cgKGJyb3dzZXJJZDogc3RyaW5nLCBuZXdXaWR0aDogbnVtYmVyLCBuZXdIZWlnaHQ6IG51bWJlciwgY3VycmVudFdpZHRoOiBudW1iZXIsIGN1cnJlbnRIZWlnaHQ6IG51bWJlcik6IFByb21pc2U8dm9pZD47XG59XG5cbmludGVyZmFjZSBSdW50aW1lSW5mbyB7XG4gICAgYnJvd3NlcklkOiBzdHJpbmc7XG4gICAgY2RwUG9ydDogbnVtYmVyO1xuICAgIGNsaWVudDogcmVtb3RlQ2hyb21lLlByb3RvY29sQXBpO1xuICAgIHRhYjogcmVtb3RlQ2hyb21lLlRhcmdldEluZm87XG4gICAgY29uZmlnOiBDb25maWc7XG4gICAgdmlld3BvcnRTaXplOiBTaXplO1xuICAgIGVtdWxhdGVkRGV2aWNlUGl4ZWxSYXRpbzogbnVtYmVyO1xuICAgIG9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbzogbnVtYmVyO1xuICAgIHByb3ZpZGVyTWV0aG9kczogUHJvdmlkZXJNZXRob2RzO1xufVxuXG5pbnRlcmZhY2UgVG91Y2hDb25maWdPcHRpb25zIHtcbiAgICBlbmFibGVkOiBib29sZWFuO1xuICAgIGNvbmZpZ3VyYXRpb246ICdkZXNrdG9wJyB8ICdtb2JpbGUnO1xuICAgIG1heFRvdWNoUG9pbnRzOiBudW1iZXI7XG59XG5cbmNvbnN0IERPV05MT0FEU19ESVIgPSBwYXRoLmpvaW4ob3MuaG9tZWRpcigpLCAnRG93bmxvYWRzJyk7XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEFjdGl2ZVRhYiAoY2RwUG9ydDogbnVtYmVyLCBicm93c2VySWQ6IHN0cmluZyk6IFByb21pc2U8cmVtb3RlQ2hyb21lLlRhcmdldEluZm8+IHtcbiAgICBjb25zdCB0YWJzID0gYXdhaXQgcmVtb3RlQ2hyb21lLmxpc3RUYWJzKHsgcG9ydDogY2RwUG9ydCB9KTtcblxuICAgIHJldHVybiB0YWJzLmZpbHRlcih0ID0+IHQudHlwZSA9PT0gJ3BhZ2UnICYmIHQudXJsLmluY2x1ZGVzKGJyb3dzZXJJZCkpWzBdO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRFbXVsYXRpb25Cb3VuZHMgKHsgY2xpZW50LCBjb25maWcsIHZpZXdwb3J0U2l6ZSwgZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvIH06IFJ1bnRpbWVJbmZvKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgc2V0RGV2aWNlTWV0cmljc092ZXJyaWRlKGNsaWVudCwgdmlld3BvcnRTaXplLndpZHRoLCB2aWV3cG9ydFNpemUuaGVpZ2h0LCBlbXVsYXRlZERldmljZVBpeGVsUmF0aW8sIGNvbmZpZy5tb2JpbGUpO1xuXG4gICAgYXdhaXQgY2xpZW50LkVtdWxhdGlvbi5zZXRWaXNpYmxlU2l6ZSh7IHdpZHRoOiB2aWV3cG9ydFNpemUud2lkdGgsIGhlaWdodDogdmlld3BvcnRTaXplLmhlaWdodCB9KTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gc2V0RW11bGF0aW9uIChydW50aW1lSW5mbzogUnVudGltZUluZm8pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGNsaWVudCwgY29uZmlnIH0gPSBydW50aW1lSW5mbztcblxuICAgIGlmIChjb25maWcudXNlckFnZW50ICE9PSB2b2lkIDApXG4gICAgICAgIGF3YWl0IGNsaWVudC5OZXR3b3JrLnNldFVzZXJBZ2VudE92ZXJyaWRlKHsgdXNlckFnZW50OiBjb25maWcudXNlckFnZW50IH0pO1xuXG4gICAgaWYgKGNvbmZpZy50b3VjaCAhPT0gdm9pZCAwKSB7XG4gICAgICAgIGNvbnN0IHRvdWNoQ29uZmlnOiBUb3VjaENvbmZpZ09wdGlvbnMgPSB7XG4gICAgICAgICAgICBlbmFibGVkOiAgICAgICAgY29uZmlnLnRvdWNoLFxuICAgICAgICAgICAgY29uZmlndXJhdGlvbjogIGNvbmZpZy5tb2JpbGUgPyAnbW9iaWxlJyA6ICdkZXNrdG9wJyxcbiAgICAgICAgICAgIG1heFRvdWNoUG9pbnRzOiAxXG4gICAgICAgIH07XG5cbiAgICAgICAgaWYgKGNsaWVudC5FbXVsYXRpb24uc2V0RW1pdFRvdWNoRXZlbnRzRm9yTW91c2UpXG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldEVtaXRUb3VjaEV2ZW50c0Zvck1vdXNlKHRvdWNoQ29uZmlnKTtcblxuICAgICAgICBpZiAoY2xpZW50LkVtdWxhdGlvbi5zZXRUb3VjaEVtdWxhdGlvbkVuYWJsZWQpXG4gICAgICAgICAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldFRvdWNoRW11bGF0aW9uRW5hYmxlZCh0b3VjaENvbmZpZyk7XG4gICAgfVxuXG4gICAgYXdhaXQgcmVzaXplV2luZG93KHsgd2lkdGg6IGNvbmZpZy53aWR0aCwgaGVpZ2h0OiBjb25maWcuaGVpZ2h0IH0sIHJ1bnRpbWVJbmZvKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZW5hYmxlRG93bmxvYWRzICh7IGNsaWVudCB9OiBSdW50aW1lSW5mbyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IGNsaWVudC5QYWdlLnNldERvd25sb2FkQmVoYXZpb3Ioe1xuICAgICAgICBiZWhhdmlvcjogICAgICdhbGxvdycsXG4gICAgICAgIGRvd25sb2FkUGF0aDogRE9XTkxPQURTX0RJUlxuICAgIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0U2NyZWVuc2hvdERhdGEgKHsgY2xpZW50LCBjb25maWcsIGVtdWxhdGVkRGV2aWNlUGl4ZWxSYXRpbyB9OiBSdW50aW1lSW5mbywgZnVsbFBhZ2U/OiBib29sZWFuKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBsZXQgdmlld3BvcnRXaWR0aCA9IDA7XG4gICAgbGV0IHZpZXdwb3J0SGVpZ2h0ID0gMDtcblxuICAgIGlmIChmdWxsUGFnZSkge1xuICAgICAgICBjb25zdCB7IGNvbnRlbnRTaXplLCB2aXN1YWxWaWV3cG9ydCB9ID0gYXdhaXQgY2xpZW50LlBhZ2UuZ2V0TGF5b3V0TWV0cmljcygpO1xuXG4gICAgICAgIGF3YWl0IHNldERldmljZU1ldHJpY3NPdmVycmlkZShcbiAgICAgICAgICAgIGNsaWVudCxcbiAgICAgICAgICAgIE1hdGguY2VpbChjb250ZW50U2l6ZS53aWR0aCksXG4gICAgICAgICAgICBNYXRoLmNlaWwoY29udGVudFNpemUuaGVpZ2h0KSxcbiAgICAgICAgICAgIGVtdWxhdGVkRGV2aWNlUGl4ZWxSYXRpbyxcbiAgICAgICAgICAgIGNvbmZpZy5tb2JpbGUpO1xuXG4gICAgICAgIHZpZXdwb3J0V2lkdGggPSB2aXN1YWxWaWV3cG9ydC5jbGllbnRXaWR0aDtcbiAgICAgICAgdmlld3BvcnRIZWlnaHQgPSB2aXN1YWxWaWV3cG9ydC5jbGllbnRIZWlnaHQ7XG4gICAgfVxuXG4gICAgY29uc3Qgc2NyZWVuc2hvdERhdGEgPSBhd2FpdCBjbGllbnQuUGFnZS5jYXB0dXJlU2NyZWVuc2hvdCh7fSk7XG5cbiAgICBpZiAoZnVsbFBhZ2UpIHtcbiAgICAgICAgaWYgKGNvbmZpZy5lbXVsYXRpb24pIHtcbiAgICAgICAgICAgIGF3YWl0IHNldERldmljZU1ldHJpY3NPdmVycmlkZShcbiAgICAgICAgICAgICAgICBjbGllbnQsXG4gICAgICAgICAgICAgICAgY29uZmlnLndpZHRoIHx8IHZpZXdwb3J0V2lkdGgsXG4gICAgICAgICAgICAgICAgY29uZmlnLmhlaWdodCB8fCB2aWV3cG9ydEhlaWdodCxcbiAgICAgICAgICAgICAgICBlbXVsYXRlZERldmljZVBpeGVsUmF0aW8sXG4gICAgICAgICAgICAgICAgY29uZmlnLm1vYmlsZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZVxuICAgICAgICAgICAgYXdhaXQgY2xpZW50LkVtdWxhdGlvbi5jbGVhckRldmljZU1ldHJpY3NPdmVycmlkZSgpO1xuICAgIH1cblxuICAgIHJldHVybiBCdWZmZXIuZnJvbShzY3JlZW5zaG90RGF0YS5kYXRhLCAnYmFzZTY0Jyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHNldERldmljZU1ldHJpY3NPdmVycmlkZSAoY2xpZW50OiByZW1vdGVDaHJvbWUuUHJvdG9jb2xBcGksIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyLCBkZXZpY2VTY2FsZUZhY3RvcjogbnVtYmVyLCBtb2JpbGU6IGJvb2xlYW4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldERldmljZU1ldHJpY3NPdmVycmlkZSh7XG4gICAgICAgIHdpZHRoLFxuICAgICAgICBoZWlnaHQsXG4gICAgICAgIGRldmljZVNjYWxlRmFjdG9yLFxuICAgICAgICBtb2JpbGUsXG4gICAgICAgIC8vIEB0cy1pZ25vcmVcbiAgICAgICAgZml0V2luZG93OiBmYWxzZVxuICAgIH0pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ2xpZW50IChydW50aW1lSW5mbzogUnVudGltZUluZm8pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCB7IGJyb3dzZXJJZCwgY29uZmlnLCBjZHBQb3J0IH0gPSBydW50aW1lSW5mbztcblxuICAgIGxldCB0YWIgICAgPSBudWxsO1xuICAgIGxldCBjbGllbnQgPSBudWxsO1xuXG4gICAgdHJ5IHtcbiAgICAgICAgdGFiID0gYXdhaXQgZ2V0QWN0aXZlVGFiKGNkcFBvcnQsIGJyb3dzZXJJZCk7XG5cbiAgICAgICAgaWYgKCF0YWIpXG4gICAgICAgICAgICByZXR1cm47XG5cbiAgICAgICAgY2xpZW50ID0gYXdhaXQgcmVtb3RlQ2hyb21lKHsgdGFyZ2V0OiB0YWIsIHBvcnQ6IGNkcFBvcnQgfSk7XG4gICAgfVxuICAgIGNhdGNoIChlKSB7XG4gICAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBydW50aW1lSW5mby50YWIgICAgPSB0YWI7XG4gICAgcnVudGltZUluZm8uY2xpZW50ID0gY2xpZW50O1xuXG4gICAgYXdhaXQgY2xpZW50LlBhZ2UuZW5hYmxlKCk7XG4gICAgYXdhaXQgY2xpZW50Lk5ldHdvcmsuZW5hYmxlKHt9KTtcbiAgICBhd2FpdCBjbGllbnQuUnVudGltZS5lbmFibGUoKTtcblxuICAgIGNvbnN0IGRldmljZVBpeGVsUmF0aW9RdWVyeVJlc3VsdCA9IGF3YWl0IGNsaWVudC5SdW50aW1lLmV2YWx1YXRlKHsgZXhwcmVzc2lvbjogJ3dpbmRvdy5kZXZpY2VQaXhlbFJhdGlvJyB9KTtcblxuICAgIHJ1bnRpbWVJbmZvLm9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbyA9IGRldmljZVBpeGVsUmF0aW9RdWVyeVJlc3VsdC5yZXN1bHQudmFsdWU7XG4gICAgcnVudGltZUluZm8uZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvID0gY29uZmlnLnNjYWxlRmFjdG9yIHx8IHJ1bnRpbWVJbmZvLm9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbztcblxuICAgIGlmIChjb25maWcuZW11bGF0aW9uKVxuICAgICAgICBhd2FpdCBzZXRFbXVsYXRpb24ocnVudGltZUluZm8pO1xuXG4gICAgaWYgKGNvbmZpZy5oZWFkbGVzcylcbiAgICAgICAgYXdhaXQgZW5hYmxlRG93bmxvYWRzKHJ1bnRpbWVJbmZvKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGlzSGVhZGxlc3NUYWIgKHsgdGFiLCBjb25maWcgfTogUnVudGltZUluZm8pOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGFiICYmIGNvbmZpZy5oZWFkbGVzcztcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGNsb3NlVGFiICh7IHRhYiwgY2RwUG9ydCB9OiBSdW50aW1lSW5mbyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHJlbW90ZUNocm9tZS5jbG9zZVRhYih7IGlkOiB0YWIuaWQsIHBvcnQ6IGNkcFBvcnQgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cGRhdGVNb2JpbGVWaWV3cG9ydFNpemUgKHJ1bnRpbWVJbmZvOiBSdW50aW1lSW5mbyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHdpbmRvd0RpbWVuc2lvbnNRdWVyeVJlc3VsdCA9IGF3YWl0IHJ1bnRpbWVJbmZvLmNsaWVudC5SdW50aW1lLmV2YWx1YXRlKHtcbiAgICAgICAgZXhwcmVzc2lvbjogICAgYCgke0dFVF9XSU5ET1dfRElNRU5TSU9OU19JTkZPX1NDUklQVH0pKClgLFxuICAgICAgICByZXR1cm5CeVZhbHVlOiB0cnVlXG4gICAgfSk7XG5cbiAgICBjb25zdCB3aW5kb3dEaW1lbnNpb25zID0gd2luZG93RGltZW5zaW9uc1F1ZXJ5UmVzdWx0LnJlc3VsdC52YWx1ZTtcblxuICAgIHJ1bnRpbWVJbmZvLnZpZXdwb3J0U2l6ZS53aWR0aCAgPSB3aW5kb3dEaW1lbnNpb25zLm91dGVyV2lkdGg7XG4gICAgcnVudGltZUluZm8udmlld3BvcnRTaXplLmhlaWdodCA9IHdpbmRvd0RpbWVuc2lvbnMub3V0ZXJIZWlnaHQ7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiByZXNpemVXaW5kb3cgKG5ld0RpbWVuc2lvbnM6IFNpemUsIHJ1bnRpbWVJbmZvOiBSdW50aW1lSW5mbyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgYnJvd3NlcklkLCBjb25maWcsIHZpZXdwb3J0U2l6ZSwgcHJvdmlkZXJNZXRob2RzIH0gPSBydW50aW1lSW5mbztcblxuICAgIGNvbnN0IGN1cnJlbnRXaWR0aCAgPSB2aWV3cG9ydFNpemUud2lkdGg7XG4gICAgY29uc3QgY3VycmVudEhlaWdodCA9IHZpZXdwb3J0U2l6ZS5oZWlnaHQ7XG4gICAgY29uc3QgbmV3V2lkdGggICAgICA9IG5ld0RpbWVuc2lvbnMud2lkdGggfHwgY3VycmVudFdpZHRoO1xuICAgIGNvbnN0IG5ld0hlaWdodCAgICAgPSBuZXdEaW1lbnNpb25zLmhlaWdodCB8fCBjdXJyZW50SGVpZ2h0O1xuXG4gICAgaWYgKCFjb25maWcuaGVhZGxlc3MpXG4gICAgICAgIGF3YWl0IHByb3ZpZGVyTWV0aG9kcy5yZXNpemVMb2NhbEJyb3dzZXJXaW5kb3coYnJvd3NlcklkLCBuZXdXaWR0aCwgbmV3SGVpZ2h0LCBjdXJyZW50V2lkdGgsIGN1cnJlbnRIZWlnaHQpO1xuXG4gICAgdmlld3BvcnRTaXplLndpZHRoICA9IG5ld1dpZHRoO1xuICAgIHZpZXdwb3J0U2l6ZS5oZWlnaHQgPSBuZXdIZWlnaHQ7XG5cbiAgICBpZiAoY29uZmlnLmVtdWxhdGlvbilcbiAgICAgICAgYXdhaXQgc2V0RW11bGF0aW9uQm91bmRzKHJ1bnRpbWVJbmZvKTtcbn1cbiJdfQ==