Falsear la fecha en una aplicación Electron
Busca esto y todas las respuestas tratan de cambiar tu propio código - simular el objeto
Date, usar los temporizadores falsos de tu framework de pruebas. Nada de eso ayuda
cuando lo que tienes es una aplicación ya compilada. Esto ejecuta la aplicación que ya tienes.
Por qué la inyección no llega
Este modo existe por un fallo concreto. Un temporizador Pomodoro hecho con Electron se ejecutó
bajo una sesión x60 y su cuenta atrás no se movió en absoluto. Desmontar el bundle de
la aplicación mostró dos razones independientes, y ninguna tenía solución en el lado nativo:
- La cuenta atrás no leía ningún reloj. Era un contador incrementado por
setInterval, ejecutándose dentro de un Web Worker. No había ninguna llamada de tiempo que interceptar, porque la aplicación nunca preguntaba qué hora era. - Ese worker vive en un proceso de renderizado aislado, que es justo el lugar al que no llega una biblioteca inyectada desde fuera.
Así que el mecanismo del lado de Windows no puede ayudar aquí, y la respuesta es hablar en su lugar con el propio motor de JavaScript de la aplicación.
Qué ocurre en su lugar
La aplicación se lanza con un puerto de depuración y un perfil limpio y desechable, y sus propias
API de tiempo pasan al reloj de la sesión mediante el protocolo DevTools -
Date.now, el constructor new Date(), performance.now,
setTimeout y setInterval.
La sustitución se instala en todos los contextos que abre la aplicación, incluidos sus Web Workers - donde suele acabar viviendo el temporizador, y el único lugar al que la inyección nativa nunca iba a llegar.
No cambia nada en la forma de manejarlo. El mismo comando, la misma ventana, el mismo panel de sesión con los dos relojes y el veredicto.
# El mismo comando que para una aplicación nativa - el modo se detecta chrono run "%LOCALAPPDATA%\Programs\your-app\YourApp.exe" --at 2038-01-01T00:00:00 --mode x60
Dos límites que conviene conocer antes de empezar
El lanzamiento es invasivo, y lo dice a propósito en voz alta.
La aplicación se inicia con un puerto de depuración remota abierto y un perfil nuevo y aislado en
%TEMP% - no se ejecuta con tu perfil real, y no es la copia que ya está en tu bandeja
del sistema. El perfil se borra al terminar la sesión, y si no se pudo borrar, el resumen de la
sesión lo dice en lugar de dejarlo ahí en silencio.
Pasar tu propio --user-data-dir o --remote-debugging-port se rechaza en
lugar de sobrescribirse, porque el accidente evidente - apuntar la sesión a tu perfil real del
navegador - no es uno que merezca permitirse.
Las páginas leen la zona horaria de la sesión.
Cada página y cada worker se coloca en la zona
horaria de la sesión, un desfase fijo sin horario de verano, y comprueba el desfase que
lee, así que se informa de una página que haya leído otra zona. Dos límites:
Intl nombra esa zona como un desfase como GMT+02:00 y no como una
ciudad, y el proceso principal de una aplicación Electron ejecuta JavaScript en Node, al que
la sesión no llega, así que conserva el reloj real - el informe lo dice.
Una cosa más que sorprende: un intervalo ya programado conserva su ritmo anterior cuando
cambias la velocidad en plena sesión. Date.now, new Date() y
performance.now reaccionan de inmediato, un setInterval en marcha no, y
la sesión avisa de ello en lugar de dejar que concluyas que el cambio no hizo nada.
Cuánto está probado
Experimental, y esa palabra tiene aquí un significado definido: funciona con los objetivos con los que se construyó, no se ha probado ampliamente, y la auditoría integrada es tu fuente de verdad, no esta página. Se verificó a mano y no con la suite automatizada, con una aplicación Electron real en Windows de 64 bits.
La cobertura se informa por contexto de JavaScript y no por proceso, ya que esa es la unidad que existe aquí. Una aplicación inactiva que nunca pregunta la hora produce honestamente indeterminado - no leyó ningún reloj, así que no se puede afirmar nada sobre si habría visto el correcto. Qué significan los veredictos →