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
setIntervalwerd 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 →