313 lines
8.8 KiB
JavaScript
313 lines
8.8 KiB
JavaScript
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 = `
|
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
<path d="M9.2 16.6 4.8 12.2l-1.6 1.6 6 6L21 7.8l-1.6-1.6L9.2 16.6Z"/>
|
|
</svg>`;
|
|
|
|
const PLAY_ICON = `
|
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
<path d="M8 5v14l11-7L8 5Z"/>
|
|
</svg>`;
|
|
|
|
const SKIP_ICON = `
|
|
<svg viewBox="0 0 24 24" aria-hidden="true">
|
|
<path d="M5 7.4 6.4 6 12 11.6 17.6 6 19 7.4 13.4 13 19 18.6 17.6 20 12 14.4 6.4 20 5 18.6 10.6 13 5 7.4Z"/>
|
|
</svg>`;
|
|
|
|
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 => `
|
|
<label class="option" title="${getStepFiles(step).join(", ")}">
|
|
<input type="checkbox" data-step-option="${step.id}" ${step.enabled ? "checked" : ""}>
|
|
<span class="mini-check"></span>
|
|
<span>${step.label}</span>
|
|
</label>
|
|
`).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 `
|
|
<div class="step ${status}">
|
|
<div class="step-dot">${getStepIcon(status)}</div>
|
|
<div>${step.label}</div>
|
|
</div>
|
|
`;
|
|
}).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 `<span class="${className}">${escapeHtml(entry.line)}</span>`;
|
|
})
|
|
.join("\n");
|
|
logsEl.scrollTop = logsEl.scrollHeight;
|
|
}
|
|
|
|
function escapeHtml(value) {
|
|
return value
|
|
.replaceAll("&", "&")
|
|
.replaceAll("<", "<")
|
|
.replaceAll(">", ">")
|
|
.replaceAll('"', """)
|
|
.replaceAll("'", "'");
|
|
}
|