UNPKG

testcafe

Version:

Automated browser testing for the modern web development stack.

102 lines 15.5 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const chrome_remote_interface_1 = __importDefault(require("chrome-remote-interface")); const client_functions_1 = require("../../../utils/client-functions"); async function getActiveTab(cdpPort, browserId) { const tabs = await chrome_remote_interface_1.default.listTabs({ port: cdpPort }); const tab = tabs.filter(t => t.type === 'page' && t.url.indexOf(browserId) > -1)[0]; return tab; } async function setEmulationBounds({ client, config, viewportSize, emulatedDevicePixelRatio }) { await client.Emulation.setDeviceMetricsOverride({ width: viewportSize.width, height: viewportSize.height, deviceScaleFactor: emulatedDevicePixelRatio, mobile: config.mobile, fitWindow: false }); 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 getScreenshotData({ client }) { const screenshotData = await client.Page.captureScreenshot(); return Buffer.from(screenshotData.data, 'base64'); } exports.getScreenshotData = getScreenshotData; 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); } 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2Jyb3dzZXIvcHJvdmlkZXIvYnVpbHQtaW4vZGVkaWNhdGVkL2Nocm9tZS9jZHAuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFBQSxzRkFBbUQ7QUFDbkQsc0VBQW9GO0FBR3BGLEtBQUssVUFBVSxZQUFZLENBQUUsT0FBTyxFQUFFLFNBQVM7SUFDM0MsTUFBTSxJQUFJLEdBQUcsTUFBTSxpQ0FBWSxDQUFDLFFBQVEsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzVELE1BQU0sR0FBRyxHQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxLQUFLLE1BQU0sSUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBRXJGLE9BQU8sR0FBRyxDQUFDO0FBQ2YsQ0FBQztBQUVELEtBQUssVUFBVSxrQkFBa0IsQ0FBRSxFQUFFLE1BQU0sRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLHdCQUF3QixFQUFFO0lBQ3pGLE1BQU0sTUFBTSxDQUFDLFNBQVMsQ0FBQyx3QkFBd0IsQ0FBQztRQUM1QyxLQUFLLEVBQWMsWUFBWSxDQUFDLEtBQUs7UUFDckMsTUFBTSxFQUFhLFlBQVksQ0FBQyxNQUFNO1FBQ3RDLGlCQUFpQixFQUFFLHdCQUF3QjtRQUMzQyxNQUFNLEVBQWEsTUFBTSxDQUFDLE1BQU07UUFDaEMsU0FBUyxFQUFVLEtBQUs7S0FDM0IsQ0FBQyxDQUFDO0lBRUgsTUFBTSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxFQUFFLEtBQUssRUFBRSxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQztBQUN0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Q0FBQztJQUMxRCxNQUFNLFNBQVMsR0FBTyxhQUFhLENBQUMsTUFBTSxJQUFJLGFBQWEsQ0FBQztJQUU1RCxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVE7UUFDaEIsTUFBTSxlQUFlLENBQUMsd0JBQXdCLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBRWhILFlBQVksQ0FBQyxLQUFLLEdBQUksUUFBUSxDQUFDO0lBQy9CLFlBQVksQ0FBQyxNQUFNLEdBQUcsU0FBUyxDQUFDO0lBRWhDLElBQUksTUFBTSxDQUFDLFNBQVM7UUFDaEIsTUFBTSxrQkFBa0IsQ0FBQyxXQUFXLENBQUMsQ0FBQztBQUM5QyxDQUFDO0FBaEJELG9DQWdCQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCByZW1vdGVDaHJvbWUgZnJvbSAnY2hyb21lLXJlbW90ZS1pbnRlcmZhY2UnO1xuaW1wb3J0IHsgR0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvY2xpZW50LWZ1bmN0aW9ucyc7XG5cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QWN0aXZlVGFiIChjZHBQb3J0LCBicm93c2VySWQpIHtcbiAgICBjb25zdCB0YWJzID0gYXdhaXQgcmVtb3RlQ2hyb21lLmxpc3RUYWJzKHsgcG9ydDogY2RwUG9ydCB9KTtcbiAgICBjb25zdCB0YWIgID0gdGFicy5maWx0ZXIodCA9PiB0LnR5cGUgPT09ICdwYWdlJyAmJiB0LnVybC5pbmRleE9mKGJyb3dzZXJJZCkgPiAtMSlbMF07XG5cbiAgICByZXR1cm4gdGFiO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRFbXVsYXRpb25Cb3VuZHMgKHsgY2xpZW50LCBjb25maWcsIHZpZXdwb3J0U2l6ZSwgZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvIH0pIHtcbiAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldERldmljZU1ldHJpY3NPdmVycmlkZSh7XG4gICAgICAgIHdpZHRoOiAgICAgICAgICAgICB2aWV3cG9ydFNpemUud2lkdGgsXG4gICAgICAgIGhlaWdodDogICAgICAgICAgICB2aWV3cG9ydFNpemUuaGVpZ2h0LFxuICAgICAgICBkZXZpY2VTY2FsZUZhY3RvcjogZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvLFxuICAgICAgICBtb2JpbGU6ICAgICAgICAgICAgY29uZmlnLm1vYmlsZSxcbiAgICAgICAgZml0V2luZG93OiAgICAgICAgIGZhbHNlXG4gICAgfSk7XG5cbiAgICBhd2FpdCBjbGllbnQuRW11bGF0aW9uLnNldFZpc2libGVTaXplKHsgd2lkdGg6IHZpZXdwb3J0U2l6ZS53aWR0aCwgaGVpZ2h0OiB2aWV3cG9ydFNpemUuaGVpZ2h0IH0pO1xufVxuXG5hc3luYyBmdW5jdGlvbiBzZXRFbXVsYXRpb24gKHJ1bnRpbWVJbmZvKSB7XG4gICAgY29uc3QgeyBjbGllbnQsIGNvbmZpZyB9ID0gcnVudGltZUluZm87XG5cbiAgICBpZiAoY29uZmlnLnVzZXJBZ2VudCAhPT0gdm9pZCAwKVxuICAgICAgICBhd2FpdCBjbGllbnQuTmV0d29yay5zZXRVc2VyQWdlbnRPdmVycmlkZSh7IHVzZXJBZ2VudDogY29uZmlnLnVzZXJBZ2VudCB9KTtcblxuICAgIGlmIChjb25maWcudG91Y2ggIT09IHZvaWQgMCkge1xuICAgICAgICBjb25zdCB0b3VjaENvbmZpZyA9IHtcbiAgICAgICAgICAgIGVuYWJsZWQ6ICAgICAgICBjb25maWcudG91Y2gsXG4gICAgICAgICAgICBjb25maWd1cmF0aW9uOiAgY29uZmlnLm1vYmlsZSA/ICdtb2JpbGUnIDogJ2Rlc2t0b3AnLFxuICAgICAgICAgICAgbWF4VG91Y2hQb2ludHM6IDFcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoY2xpZW50LkVtdWxhdGlvbi5zZXRFbWl0VG91Y2hFdmVudHNGb3JNb3VzZSlcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5FbXVsYXRpb24uc2V0RW1pdFRvdWNoRXZlbnRzRm9yTW91c2UodG91Y2hDb25maWcpO1xuXG4gICAgICAgIGlmIChjbGllbnQuRW11bGF0aW9uLnNldFRvdWNoRW11bGF0aW9uRW5hYmxlZClcbiAgICAgICAgICAgIGF3YWl0IGNsaWVudC5FbXVsYXRpb24uc2V0VG91Y2hFbXVsYXRpb25FbmFibGVkKHRvdWNoQ29uZmlnKTtcbiAgICB9XG5cbiAgICBhd2FpdCByZXNpemVXaW5kb3coeyB3aWR0aDogY29uZmlnLndpZHRoLCBoZWlnaHQ6IGNvbmZpZy5oZWlnaHQgfSwgcnVudGltZUluZm8pO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZ2V0U2NyZWVuc2hvdERhdGEgKHsgY2xpZW50IH0pIHtcbiAgICBjb25zdCBzY3JlZW5zaG90RGF0YSA9IGF3YWl0IGNsaWVudC5QYWdlLmNhcHR1cmVTY3JlZW5zaG90KCk7XG5cbiAgICByZXR1cm4gQnVmZmVyLmZyb20oc2NyZWVuc2hvdERhdGEuZGF0YSwgJ2Jhc2U2NCcpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY3JlYXRlQ2xpZW50IChydW50aW1lSW5mbykge1xuICAgIGNvbnN0IHsgYnJvd3NlcklkLCBjb25maWcsIGNkcFBvcnQgfSA9IHJ1bnRpbWVJbmZvO1xuXG4gICAgbGV0IHRhYiAgICA9IG51bGw7XG4gICAgbGV0IGNsaWVudCA9IG51bGw7XG5cbiAgICB0cnkge1xuICAgICAgICB0YWIgPSBhd2FpdCBnZXRBY3RpdmVUYWIoY2RwUG9ydCwgYnJvd3NlcklkKTtcblxuICAgICAgICBpZiAoIXRhYilcbiAgICAgICAgICAgIHJldHVybjtcblxuICAgICAgICBjbGllbnQgPSBhd2FpdCByZW1vdGVDaHJvbWUoeyB0YXJnZXQ6IHRhYiwgcG9ydDogY2RwUG9ydCB9KTtcbiAgICB9XG4gICAgY2F0Y2ggKGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHJ1bnRpbWVJbmZvLnRhYiAgICA9IHRhYjtcbiAgICBydW50aW1lSW5mby5jbGllbnQgPSBjbGllbnQ7XG5cbiAgICBhd2FpdCBjbGllbnQuUGFnZS5lbmFibGUoKTtcbiAgICBhd2FpdCBjbGllbnQuTmV0d29yay5lbmFibGUoKTtcbiAgICBhd2FpdCBjbGllbnQuUnVudGltZS5lbmFibGUoKTtcblxuICAgIGNvbnN0IGRldmljZVBpeGVsUmF0aW9RdWVyeVJlc3VsdCA9IGF3YWl0IGNsaWVudC5SdW50aW1lLmV2YWx1YXRlKHsgZXhwcmVzc2lvbjogJ3dpbmRvdy5kZXZpY2VQaXhlbFJhdGlvJyB9KTtcblxuICAgIHJ1bnRpbWVJbmZvLm9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbyA9IGRldmljZVBpeGVsUmF0aW9RdWVyeVJlc3VsdC5yZXN1bHQudmFsdWU7XG4gICAgcnVudGltZUluZm8uZW11bGF0ZWREZXZpY2VQaXhlbFJhdGlvID0gY29uZmlnLnNjYWxlRmFjdG9yIHx8IHJ1bnRpbWVJbmZvLm9yaWdpbmFsRGV2aWNlUGl4ZWxSYXRpbztcblxuICAgIGlmIChjb25maWcuZW11bGF0aW9uKVxuICAgICAgICBhd2FpdCBzZXRFbXVsYXRpb24ocnVudGltZUluZm8pO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaXNIZWFkbGVzc1RhYiAoeyB0YWIsIGNvbmZpZyB9KSB7XG4gICAgcmV0dXJuIHRhYiAmJiBjb25maWcuaGVhZGxlc3M7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBjbG9zZVRhYiAoeyB0YWIsIGNkcFBvcnQgfSkge1xuICAgIGF3YWl0IHJlbW90ZUNocm9tZS5jbG9zZVRhYih7IGlkOiB0YWIuaWQsIHBvcnQ6IGNkcFBvcnQgfSk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB1cGRhdGVNb2JpbGVWaWV3cG9ydFNpemUgKHJ1bnRpbWVJbmZvKSB7XG4gICAgY29uc3Qgd2luZG93RGltZW5zaW9uc1F1ZXJ5UmVzdWx0ID0gYXdhaXQgcnVudGltZUluZm8uY2xpZW50LlJ1bnRpbWUuZXZhbHVhdGUoe1xuICAgICAgICBleHByZXNzaW9uOiAgICBgKCR7R0VUX1dJTkRPV19ESU1FTlNJT05TX0lORk9fU0NSSVBUfSkoKWAsXG4gICAgICAgIHJldHVybkJ5VmFsdWU6IHRydWVcbiAgICB9KTtcblxuICAgIGNvbnN0IHdpbmRvd0RpbWVuc2lvbnMgPSB3aW5kb3dEaW1lbnNpb25zUXVlcnlSZXN1bHQucmVzdWx0LnZhbHVlO1xuXG4gICAgcnVudGltZUluZm8udmlld3BvcnRTaXplLndpZHRoICA9IHdpbmRvd0RpbWVuc2lvbnMub3V0ZXJXaWR0aDtcbiAgICBydW50aW1lSW5mby52aWV3cG9ydFNpemUuaGVpZ2h0ID0gd2luZG93RGltZW5zaW9ucy5vdXRlckhlaWdodDtcbn1cblxuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlc2l6ZVdpbmRvdyAobmV3RGltZW5zaW9ucywgcnVudGltZUluZm8pIHtcbiAgICBjb25zdCB7IGJyb3dzZXJJZCwgY29uZmlnLCB2aWV3cG9ydFNpemUsIHByb3ZpZGVyTWV0aG9kcyB9ID0gcnVudGltZUluZm87XG5cbiAgICBjb25zdCBjdXJyZW50V2lkdGggID0gdmlld3BvcnRTaXplLndpZHRoO1xuICAgIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSB2aWV3cG9ydFNpemUuaGVpZ2h0O1xuICAgIGNvbnN0IG5ld1dpZHRoICAgICAgPSBuZXdEaW1lbnNpb25zLndpZHRoIHx8IGN1cnJlbnRXaWR0aDtcbiAgICBjb25zdCBuZXdIZWlnaHQgICAgID0gbmV3RGltZW5zaW9ucy5oZWlnaHQgfHwgY3VycmVudEhlaWdodDtcblxuICAgIGlmICghY29uZmlnLmhlYWRsZXNzKVxuICAgICAgICBhd2FpdCBwcm92aWRlck1ldGhvZHMucmVzaXplTG9jYWxCcm93c2VyV2luZG93KGJyb3dzZXJJZCwgbmV3V2lkdGgsIG5ld0hlaWdodCwgY3VycmVudFdpZHRoLCBjdXJyZW50SGVpZ2h0KTtcblxuICAgIHZpZXdwb3J0U2l6ZS53aWR0aCAgPSBuZXdXaWR0aDtcbiAgICB2aWV3cG9ydFNpemUuaGVpZ2h0ID0gbmV3SGVpZ2h0O1xuXG4gICAgaWYgKGNvbmZpZy5lbXVsYXRpb24pXG4gICAgICAgIGF3YWl0IHNldEVtdWxhdGlvbkJvdW5kcyhydW50aW1lSW5mbyk7XG59XG4iXX0=