const DEPLOY_STEPS = [ { id: "export-project", label: "Exportar proyecto", file: "export-project.js", enabled: true }, { id: "increment-version", label: "Incrementar y bloquear version", files: ["increment-version.js", "lock-version-history.js"], enabled: true, linkedToggle: "toggle-increment-version" }, { id: "generate-source-code", label: "Generar codigo", file: "generate-source-code.js", enabled: true } ]; const REPORTS_DOWNLOAD_URL = "http://172.27.197.229:8092/scriptcase/app/GT_ARIES/blank_PROCESAR_DESCARGAR_REPORTES/"; const SCRIPT_DELAY_MS = 2500; const CHECK_ICON = ` `; const PLAY_ICON = ` `; const SKIP_ICON = ` `; const state = { running: false, stepStatus: Object.fromEntries(DEPLOY_STEPS.map(step => [step.id, "pending"])), logs: [] }; const sleep = ms => new Promise(resolve => setTimeout(resolve, ms)); const stepsEl = document.getElementById("steps"); const optionsEl = document.getElementById("step-options"); const logsEl = document.getElementById("logs"); const runButton = document.getElementById("run-deploy"); const generateIdButton = document.getElementById("generate-test-id"); const downloadReportsButton = document.getElementById("download-reports-folder"); const clearLogsButton = document.getElementById("clear-logs"); const incrementToggle = document.getElementById("toggle-increment-version"); document.addEventListener("DOMContentLoaded", init); async function init() { renderOptions(); renderSteps(); bindEvents(); await restoreOptions(); syncIncrementOption(); renderSteps(); log("INFO", "Deploy Master listo."); } function bindEvents() { runButton.addEventListener("click", runDeploy); generateIdButton.addEventListener("click", generateTestId); downloadReportsButton.addEventListener("click", openReportsFolder); clearLogsButton.addEventListener("click", () => { state.logs = []; renderLogs(); }); incrementToggle.addEventListener("change", () => { syncIncrementOption(); persistOptions(); renderSteps(); }); } function renderOptions() { optionsEl.innerHTML = DEPLOY_STEPS.map(step => ` `).join(""); optionsEl.querySelectorAll("[data-step-option]").forEach(input => { input.addEventListener("change", () => { const step = DEPLOY_STEPS.find(item => item.id === input.dataset.stepOption); step.enabled = input.checked; if (step.linkedToggle === "toggle-increment-version") { incrementToggle.checked = input.checked; } persistOptions(); renderSteps(); }); }); } function renderSteps() { stepsEl.innerHTML = DEPLOY_STEPS.map(step => { const status = step.enabled ? state.stepStatus[step.id] : "skipped"; return `
${getStepIcon(status)}
${step.label}
`; }).join(""); } function getStepIcon(status) { if (status === "running") return PLAY_ICON; if (status === "skipped") return SKIP_ICON; return CHECK_ICON; } async function runDeploy() { if (state.running) return; const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab?.id) { log("ERROR", "No se pudo detectar la pestaña activa."); return; } const selectedSteps = DEPLOY_STEPS.filter(step => step.enabled); if (!selectedSteps.length) { log("WARN", "No hay pasos seleccionados para ejecutar."); return; } setRunning(true); resetStepStatus(); log("INFO", "Deploy iniciado..."); try { for (const step of DEPLOY_STEPS) { if (!step.enabled) { setStepStatus(step.id, "skipped"); log("INFO", `Saltando ${getStepFiles(step).join(", ")}.`); continue; } setStepStatus(step.id, "running"); log("INFO", `Ejecutando ${getStepFiles(step).join(", ")}...`); const stepFiles = getStepFiles(step); for (const [index, file] of stepFiles.entries()) { await chrome.scripting.executeScript({ target: { tabId: tab.id, allFrames: false }, files: [file] }); if (index < stepFiles.length - 1) { log("INFO", `Esperando ${SCRIPT_DELAY_MS / 1000}s antes del siguiente script...`); await sleep(SCRIPT_DELAY_MS); } } setStepStatus(step.id, "done"); log("INFO", `${step.label} finalizado.`); } log("SUCCESS", "Deploy completado exitosamente!"); } catch (error) { const runningStep = DEPLOY_STEPS.find(step => state.stepStatus[step.id] === "running"); if (runningStep) { setStepStatus(runningStep.id, "error"); } log("ERROR", error?.message || "Ocurrio un error al ejecutar el deploy."); } finally { setRunning(false); } } async function openReportsFolder() { await chrome.tabs.create({ url: REPORTS_DOWNLOAD_URL }); log("INFO", "Abriendo descarga de carpeta de reportes."); } async function generateTestId() { const [tab] = await chrome.tabs.query({ active: true, currentWindow: true }); if (!tab?.id) { log("ERROR", "No se pudo detectar la pestaña activa."); return; } try { const [{ result }] = await chrome.scripting.executeScript({ target: { tabId: tab.id }, func: generateAndCopyTestId }); log("INFO", `ID generado: ${result}`); } catch (error) { log("ERROR", error?.message || "No se pudo generar el ID de prueba."); } } function generateAndCopyTestId() { const now = new Date(); const pad = value => String(value).padStart(2, "0"); const id = `TEST-${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`; const textarea = document.createElement("textarea"); textarea.value = id; textarea.style.position = "fixed"; textarea.style.top = "0"; textarea.style.left = "0"; textarea.style.opacity = "0"; document.body.appendChild(textarea); textarea.select(); document.execCommand("copy"); document.body.removeChild(textarea); return id; } function resetStepStatus() { DEPLOY_STEPS.forEach(step => { state.stepStatus[step.id] = step.enabled ? "pending" : "skipped"; }); renderSteps(); } function setStepStatus(stepId, status) { state.stepStatus[stepId] = status; renderSteps(); } function setRunning(isRunning) { state.running = isRunning; runButton.disabled = isRunning; generateIdButton.disabled = isRunning; downloadReportsButton.disabled = isRunning; runButton.textContent = isRunning ? "Ejecutando..." : "Ejecutar Deploy"; } function syncIncrementOption() { const incrementStep = DEPLOY_STEPS.find(step => step.id === "increment-version"); incrementStep.enabled = incrementToggle.checked; const option = optionsEl.querySelector('[data-step-option="increment-version"]'); if (option) { option.checked = incrementToggle.checked; } } async function restoreOptions() { const { deployStepOptions } = await chrome.storage.local.get("deployStepOptions"); if (!deployStepOptions) return; DEPLOY_STEPS.forEach(step => { if (typeof deployStepOptions[step.id] === "boolean") { step.enabled = deployStepOptions[step.id]; } }); incrementToggle.checked = DEPLOY_STEPS.find(step => step.id === "increment-version").enabled; optionsEl.querySelectorAll("[data-step-option]").forEach(input => { const step = DEPLOY_STEPS.find(item => item.id === input.dataset.stepOption); input.checked = step.enabled; }); } async function persistOptions() { const deployStepOptions = Object.fromEntries(DEPLOY_STEPS.map(step => [step.id, step.enabled])); await chrome.storage.local.set({ deployStepOptions }); } function getStepFiles(step) { return step.files || [step.file]; } function log(level, message) { const line = `[${level}] ${message}`; state.logs.push({ level, line }); renderLogs(); } function renderLogs() { logsEl.innerHTML = state.logs .map(entry => { const className = entry.level === "SUCCESS" ? "log-success" : ""; return `${escapeHtml(entry.line)}`; }) .join("\n"); logsEl.scrollTop = logsEl.scrollHeight; } function escapeHtml(value) { return value .replaceAll("&", "&") .replaceAll("<", "<") .replaceAll(">", ">") .replaceAll('"', """) .replaceAll("'", "'"); }