Chrono Mock
TaalNederlands

De datum vervalsen in een Electron-app

Zoek ernaar en elk antwoord gaat over het veranderen van je eigen code - het Date-object mocken, de nep-timers van je testframework gebruiken. Niets daarvan helpt als wat je hebt een kant-en-klare applicatie is. Dit draait de applicatie die je al hebt.

Waarom injectie er niet bij komt

Deze modus bestaat vanwege een specifiek falen. Een op Electron gebouwde pomodoro-timer werd onder een x60-sessie gedraaid en zijn afteltijd bewoog helemaal niet. Het uit elkaar halen van de bundel van de applicatie liet twee onafhankelijke redenen zien, en voor geen van beide was er een oplossing aan de native kant:

  • De aftelling las geen klok. Het was een teller die door setInterval werd opgehoogd, draaiend in een Web Worker. Er was geen tijdaanroep om te onderscheppen, omdat de applicatie nooit vroeg hoe laat het was.
  • Die worker leeft in een afgeschermd renderer-proces, en dat is precies de plek waar een van buiten geïnjecteerde bibliotheek niet binnenkomt.

Het mechanisme aan de Windows-kant kan hier dus niet helpen, en het antwoord is om in plaats daarvan tegen de eigen JavaScript-engine van de applicatie te praten.

Wat er in plaats daarvan gebeurt

De applicatie wordt gestart met een debugpoort en een schoon wegwerpprofiel, en haar eigen tijd-API's worden via het DevTools-protocol op de sessieklok gezet - Date.now, de constructor new Date(), performance.now, setTimeout en setInterval.

De overschrijving wordt geïnstalleerd in elke context die de applicatie opent, inclusief haar Web Workers - waar de timer meestal blijkt te zitten, en de ene plek die native injectie nooit kon bereiken.

Aan hoe je het bedient verandert niets. Hetzelfde commando, hetzelfde venster, hetzelfde sessiepaneel met de twee klokken en het oordeel.

# Hetzelfde commando als voor een native applicatie - de modus wordt gedetecteerd
chrono run "%LOCALAPPDATA%\Programs\your-app\YourApp.exe" --at 2038-01-01T00:00:00 --mode x60

Twee beperkingen om te kennen voordat je begint

De start is ingrijpend, en bewust luid daarover.

De applicatie wordt gestart met een open remote-debugpoort en een vers, geïsoleerd profiel onder %TEMP% - ze draait niet op je echte profiel, en het is niet de kopie die al in je systeemvak zit. Het profiel wordt aan het einde van de sessie verwijderd, en als dat niet lukte, zegt de sessiesamenvatting dat in plaats van het stilletjes te laten liggen.

Je eigen --user-data-dir of --remote-debugging-port doorgeven wordt geweigerd in plaats van overschreven, omdat het voor de hand liggende ongeluk - de sessie op je echte browserprofiel richten - er niet een is dat het waard is toe te staan.

De pagina's lezen de tijdzone van de sessie.

Elke pagina en elke worker wordt op de sessietijdzone gezet, een vaste afwijking zonder zomertijd, en controleert de afwijking die hij leest, dus een pagina die een andere zone las, wordt gemeld. Twee grenzen: Intl noemt die zone een afwijking zoals GMT+02:00 en geen stad, en het hoofdproces van een Electron-toepassing draait JavaScript in Node, waar de sessie niet bij kan, dus het houdt de echte klok - het rapport zegt dat.

Nog iets wat mensen verrast: een interval dat al is ingepland behoudt zijn oude tempo als je de snelheid midden in de sessie wijzigt. Date.now, new Date() en performance.now reageren meteen, een lopende setInterval niet, en de sessie waarschuwt daarvoor in plaats van je te laten concluderen dat de wijziging niets deed.

Hoe goed is het getest

Experimenteel, en dat woord heeft hier een vaste betekenis: het werkt op de doelen waarvoor het is gebouwd, het is niet breed getest, en de ingebouwde audit is jouw bron van waarheid, niet deze pagina. Het is met de hand geverifieerd en niet met de geautomatiseerde suite, tegen een echte Electron-applicatie op 64-bits Windows.

De dekking wordt per JavaScript-context gerapporteerd en niet per proces, omdat dat de eenheid is die hier bestaat. Een applicatie die stilzit en nooit naar de tijd vraagt, levert eerlijk onbepaald op - ze las geen klok, dus er valt niets te beweren over of ze de juiste zou hebben gezien. Wat de oordelen betekenen →

Probeer het