+
diff --git a/src/logs/debug.log b/src/logs/debug.log
index b9036fb..eaf5049 100644
--- a/src/logs/debug.log
+++ b/src/logs/debug.log
@@ -57,3 +57,81 @@
29/09/2026 23:52:16 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
29/09/2026 23:52:16 - 0|CORE|✅ Modulo node-hid cargado correctamente.
29/09/2026 23:52:16 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:03:28 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:03:28 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:03:28 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:05:39 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:05:39 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:05:39 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:05:49 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:05:49 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:05:49 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:06:42 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:06:42 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:06:42 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:07:32 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:07:32 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:07:32 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:13:25 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:13:25 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:13:25 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:14:15 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:14:15 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:14:15 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:14:18 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:15:21 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:15:21 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:15:21 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:15:24 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:15:33 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:15:33 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:15:33 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:15:37 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:16:00 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:16:00 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:16:00 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:16:05 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:16:14 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:16:14 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:16:14 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:16:17 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:17:40 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:17:40 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:17:40 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:17:43 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:18:05 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:18:05 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:18:05 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:18:08 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:04 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:04 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:04 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:08 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:17 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:17 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:17 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:20 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:25 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:25 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:25 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:28 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:34 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:34 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:34 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:37 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:39 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:39 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:39 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:42 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:48 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:48 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:48 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:51 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:19:56 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:19:56 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:19:56 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:19:59 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
+30/09/2026 00:20:01 - 0|CORE|🕵️. Buscando Modulo USB para el S.O - linux_x64_gui
+30/09/2026 00:20:01 - 0|CORE|✅ Modulo node-hid cargado correctamente.
+30/09/2026 00:20:01 - 0|CORE|⏳ Iniciando Ema Libre en Modo gráfico o Web.
+30/09/2026 00:20:04 - 0|CORE|🔚 SALIR: Se cerro el core de EMA LIBRE. Hasta luego!!!.
diff --git a/test/ui-smoke.cjs b/test/ui-smoke.cjs
index 1da8931..2ce94fb 100644
--- a/test/ui-smoke.cjs
+++ b/test/ui-smoke.cjs
@@ -27,6 +27,7 @@ async function probe() {
const check = (value, message) => { if (!value) throw new Error(message); };
const tests = [];
try {
+ nw.Window.get().show();
await wait(200);
check($.fn.jquery.startsWith('3.'), 'Expected jQuery 3');
check(bootstrap.Tooltip.VERSION.startsWith('5.'), 'Expected Bootstrap 5');
@@ -36,6 +37,33 @@ async function probe() {
check(document.querySelector(tab.dataset.bsTarget)?.classList.contains('active'), 'Tab failed: ' + tab.id);
}
tests.push('all navigation tabs');
+ const home = document.getElementById('inicio');
+ home.innerHTML = window.homeHTML;
+ document.getElementById('inicio-tab').click();
+ const live = {state:[true,''], system:'SI', record:{fecha:'30/09/2026 12:00:00', temperatura_externa:0, humedad_externa:65, viento_velocidad:10, lluvia_acu_diaria:2.5}, publications:[]};
+ EstadoUI.render(live);
+ check(home.querySelectorAll('.ema-measurement').length === 4, 'Missing measurement cards');
+ const temperature = home.querySelector('[data-medicion="temperatura_externa"]');
+ check(temperature.textContent.includes('0°C'), 'Zero temperature treated as missing');
+ temperature.focus(); EstadoUI.render(live);
+ check(document.activeElement === temperature, 'Refresh lost focused measurement');
+ EstadoUI.render({...live, system:'SA'});
+ check(temperature.textContent.includes('32°F'), 'Home imperial conversion failed');
+ EstadoUI.render({...live, record:false});
+ check(temperature.textContent.includes('—'), 'Missing measurement shown as zero');
+ EstadoUI.render(live);
+ temperature.click();
+ check(document.getElementById('exterior').classList.contains('active'), 'Card detail navigation failed');
+ document.getElementById('inicio-tab').click();
+ await wait(250);
+ check(getComputedStyle(document.querySelector('#list-tab .nav-link.active')).backgroundColor === 'rgb(26, 96, 111)', 'Active navigation palette missing: ' + getComputedStyle(document.querySelector('#list-tab .nav-link.active')).backgroundColor);
+ check(getComputedStyle(document.getElementById('estado-estacion')).position === 'sticky', 'Status is not sticky');
+ for (const id of ['botoniniciar','botondetener','inombre','imodo','estado','iusb','mensaje','mensajedetalle','tamanio_diario','tamanio_pendiente','tamanio_debug','audiomenu','autoactivado','iso','nwjs_v','node_pid','node_ppid']) check(home.querySelector('#'+id), 'Missing existing control: '+id);
+ nw.Window.get().show(); await wait(350);
+ const homeCapture = await new Promise(resolve => nw.Window.get().capturePage(resolve, {format:'png', datatype:'buffer'}));
+ require('fs').writeFileSync(window.resultFile + '.inicio.png', homeCapture);
+ tests.push('home live cards, units, missing data, stable focus, detail links, active navigation and sticky status');
+
const statsRoot = document.getElementById('estadisticas');
statsRoot.innerHTML = window.statisticsHTML;
const records = [
@@ -128,6 +156,10 @@ async function probe() {
language: {url: window.languageURL}, initComplete() { resolve(this.api()); }});
});
check(table.rows().count() === 2, 'Missing table rows');
+ check(document.querySelector('#table tbody .ema-number'), 'Numeric cells not aligned');
+ const selectedRow = document.querySelector('#table tbody tr'); selectedRow.click();
+ check(selectedRow.classList.contains('ema-selected'), 'Row selection missing');
+ check(!!document.querySelector('.dataTables_scrollHead'), 'Fixed table header missing');
table.search('Beta').draw();
check(table.rows({search: 'applied'}).count() === 1, 'Table search failed');
check(table.buttons.exportData().body[0][0] === 'Beta', 'CSV/copy data failed');
@@ -179,9 +211,9 @@ async function run(mode, origin) {
const fixture = require('./fixtures/configuracion.cjs')();
fs.writeFileSync(path.join(folder, 'index.html'), `
-${head}