Falsificando a data em um aplicativo Electron
Pesquise por isso e toda resposta é sobre mudar o seu próprio código - simular o objeto
Date, usar os temporizadores falsos do seu framework de testes. Nada disso ajuda
quando o que você tem é um aplicativo já compilado. Isto executa o aplicativo que você já tem.
Por que a injeção não chega até ele
Este modo existe por causa de uma falha específica. Um temporizador Pomodoro feito em Electron foi
executado sob uma sessão x60 e a contagem regressiva dele não se mexeu. Desmontar o
bundle do aplicativo mostrou duas razões independentes, e nenhuma tinha solução no lado nativo:
- A contagem regressiva não lia nenhum relógio. Era um contador incrementado por
setInterval, rodando dentro de um Web Worker. Não havia chamada de tempo para interceptar, porque o aplicativo nunca perguntava que horas eram. - Esse worker vive em um processo de renderização isolado, que é justamente o lugar em que uma biblioteca injetada de fora não entra.
Então o mecanismo do lado do Windows não pode ajudar aqui, e a resposta é falar com o próprio motor JavaScript do aplicativo.
O que acontece em vez disso
O aplicativo é iniciado com uma porta de depuração e um perfil limpo e descartável, e as próprias
APIs de tempo dele são colocadas no relógio da sessão por meio do protocolo DevTools -
Date.now, o construtor new Date(), performance.now,
setTimeout e setInterval.
A substituição é instalada em todo contexto que o aplicativo abre, inclusive nos Web Workers - onde o temporizador costuma estar, e o único lugar que a injeção nativa nunca ia alcançar.
Nada muda na forma de operar. O mesmo comando, a mesma janela, o mesmo painel de sessão com os dois relógios e o veredito.
# O mesmo comando de um aplicativo nativo - o modo é detectado chrono run "%LOCALAPPDATA%\Programs\your-app\YourApp.exe" --at 2038-01-01T00:00:00 --mode x60
Dois limites que vale conhecer antes de começar
A inicialização é invasiva, e deliberadamente barulhenta sobre isso.
O aplicativo é iniciado com uma porta de depuração remota aberta e um perfil novo e isolado em
%TEMP% - ele não roda no seu perfil real, e não é a cópia que já está na sua bandeja
do sistema. O perfil é apagado quando a sessão termina, e, se não puder ser, o resumo da sessão
diz isso em vez de deixá-lo ali em silêncio.
Passar o seu próprio --user-data-dir ou --remote-debugging-port é
recusado em vez de sobrescrito, porque o acidente óbvio - apontar a sessão para o seu perfil real
do navegador - não é um que valha a pena permitir.
As páginas leem o fuso horário da sessão.
Cada página e cada worker é colocado no fuso horário
da sessão, um deslocamento fixo sem horário de verão, e confere o deslocamento que lê,
então uma página que leu outro fuso é reportada. Dois limites: o Intl nomeia
esse fuso como um deslocamento, como GMT+02:00, e não como uma cidade, e o
processo principal de um aplicativo Electron executa JavaScript no Node, que a sessão não
alcança, então ele mantém o relógio real - o relatório diz isso.
Mais uma coisa que surpreende: um intervalo já agendado mantém o ritmo antigo quando você
muda a velocidade no meio da sessão. Date.now, new Date() e
performance.now reagem imediatamente, um setInterval em execução não, e
a sessão avisa isso em vez de deixar você concluir que a mudança não fez nada.
Quão bem testado é
Experimental, e essa palavra tem aqui um significado definido: funciona nos alvos para os quais foi construído, não foi testado amplamente, e a auditoria integrada é a sua fonte da verdade, não esta página. Foi verificado manualmente e não pela suíte automatizada, em um aplicativo Electron real no Windows de 64 bits.
A cobertura é relatada por contexto JavaScript e não por processo, já que essa é a unidade que existe aqui. Um aplicativo parado que nunca pergunta a hora produz honestamente indeterminado - ele não leu nenhum relógio, então nada pode ser afirmado sobre se teria visto o certo. O que os vereditos significam →