Podmiana daty w aplikacji Electron
Poszukaj tego, a każda odpowiedź dotyczy zmiany własnego kodu - podmień obiekt
Date, użyj sztucznych timerów z frameworka testowego. Nic z tego nie
pomaga, gdy masz gotową, zbudowaną aplikację. To uruchamia tę, którą już masz.
Dlaczego wstrzyknięcie tam nie sięga
Ten tryb powstał z konkretnej porażki. Minutnik Pomodoro zbudowany na Electronie
został uruchomiony w sesji x60 i jego odliczanie nie ruszyło się wcale.
Rozłożenie paczki aplikacji pokazało dwa niezależne powody i żaden nie miał naprawy po
stronie natywnej:
- Odliczanie w ogóle nie czytało zegara. Był to licznik zwiększany przez
setInterval, działający wewnątrz Web Workera. Nie było wywołania czasu do przechwycenia, bo aplikacja nigdy nie pytała, która godzina. - Ten worker żyje w piaskowanym procesie renderera, czyli dokładnie tam, gdzie biblioteka wstrzyknięta z zewnątrz się nie dostaje.
Mechanizm windowsowy nie może więc tu pomóc, a odpowiedzią jest rozmowa z własnym silnikiem JavaScriptu aplikacji.
Co dzieje się zamiast tego
Aplikacja jest uruchamiana z portem debugowania i czystym, jednorazowym profilem, a jej
własne API czasu zostają przestawione na zegar sesji przez protokół DevTools -
Date.now, konstruktor new Date(),
performance.now, setTimeout i setInterval.
Nadpisanie trafia do każdego kontekstu, jaki aplikacja otwiera, łącznie z Web Workerami - czyli tam, gdzie zwykle okazuje się mieszkać timer, i w to jedno miejsce, do którego natywne wstrzyknięcie i tak by nie dotarło.
Sposób sterowania nie zmienia się w niczym. Ta sama komenda, to samo okno, ten sam panel sesji z dwoma zegarami i werdyktem.
# Ta sama komenda co dla aplikacji natywnej - tryb jest wykrywany chrono run "%LOCALAPPDATA%\Programs\your-app\YourApp.exe" --at 2038-01-01T00:00:00 --mode x60
Dwa ograniczenia, o których warto wiedzieć przed startem
Uruchomienie jest inwazyjne i celowo o tym głośno mówi.
Aplikacja startuje z otwartym portem zdalnego debugowania i świeżym, izolowanym
profilem w %TEMP% - nie działa na twoim prawdziwym profilu i nie jest tą
kopią, którą masz już w zasobniku. Profil jest kasowany po zakończeniu sesji, a jeśli
skasować się nie dał, podsumowanie sesji mówi o tym wprost, zamiast po cichu go
zostawiać.
Przekazanie własnego --user-data-dir albo
--remote-debugging-port jest odmawiane, a nie nadpisywane, bo oczywisty
wypadek - wycelowanie sesji w twój prawdziwy profil przeglądarki - nie jest wart
dopuszczenia.
Strefa czasowa sesji idzie za hostem.
W tym trybie fałszowana jest chwila, ale nie funkcje czasu lokalnego, więc niezależna strefa czasowa jest funkcją wyłącznie trybu natywnego. To ograniczenie tej wersji, a nie decyzja.
Jeszcze jedna rzecz, która zaskakuje: interwał już zaplanowany zachowuje stare
tempo, gdy zmienisz prędkość w trakcie sesji. Date.now,
new Date() i performance.now reagują natychmiast, działający
setInterval nie, a sesja ostrzega o tym, zamiast pozwolić ci wyciągnąć
wniosek, że zmiana nic nie dała.
Jak dobrze to jest przetestowane
Eksperymentalnie, a to słowo ma tu zdefiniowane znaczenie: działa na celach, na których było budowane, nie było testowane szeroko, a źródłem prawdy jest wbudowany audyt, a nie ta strona. Zostało zweryfikowane ręcznie, a nie przez zautomatyzowany zestaw, na prawdziwej aplikacji Electron na 64-bitowym Windows.
Pokrycie jest raportowane per kontekst JavaScriptu, a nie per proces, bo to jest tutaj istniejąca jednostka. Aplikacja stojąca bezczynnie i nigdy niepytająca o czas uczciwie daje werdykt nieokreślony - nie czytała zegara, więc nie da się twierdzić niczego o tym, czy zobaczyłaby właściwy. Co znaczą werdykty →