|
7 | 7 | <head> |
8 | 8 | <title>Clock Drift Simulation</title> |
9 | 9 | <script> |
10 | | - // Save original performance.now |
| 10 | + // Save original performance.now and Date.now |
11 | 11 | var origPerformanceNow = performance.now.bind(performance); |
12 | 12 | var origDateNow = Date.now.bind(Date); |
13 | 13 |
|
14 | 14 | // Capture the initial values at page load |
15 | 15 | var frozenPerformanceValue = null; |
16 | | - var freezeStartTime = null; |
| 16 | + var mockDateOffset = 0; |
17 | 17 |
|
18 | | - // Function to simulate clock drift by freezing performance.now() |
19 | | - window.simulateClockFreeze = function(durationMs) { |
20 | | - if (!frozenPerformanceValue) { |
21 | | - frozenPerformanceValue = origPerformanceNow(); |
22 | | - freezeStartTime = origDateNow(); |
| 18 | + // Function to simulate clock drift by freezing performance.now() and advancing Date.now() |
| 19 | + window.simulateClockFreeze = function(driftDurationMs) { |
| 20 | + return new Promise(resolve => { |
| 21 | + // Freeze performance.now() at current value on first call, or keep it frozen |
| 22 | + if (frozenPerformanceValue === null) { |
| 23 | + frozenPerformanceValue = origPerformanceNow(); |
| 24 | + |
| 25 | + // Override performance.now to return frozen value |
| 26 | + performance.now = function() { |
| 27 | + return frozenPerformanceValue; |
| 28 | + }; |
| 29 | + |
| 30 | + console.log('Clock frozen at performance.now() =', frozenPerformanceValue); |
| 31 | + } |
| 32 | + |
| 33 | + // Advance Date.now() by the drift amount (instant, no waiting) |
| 34 | + mockDateOffset += driftDurationMs; |
23 | 35 |
|
24 | | - // Override performance.now to return frozen value |
25 | | - performance.now = function() { |
26 | | - return frozenPerformanceValue; |
| 36 | + Date.now = function() { |
| 37 | + return origDateNow() + mockDateOffset; |
27 | 38 | }; |
28 | 39 |
|
29 | | - console.log('Clock frozen at performance.now() =', frozenPerformanceValue); |
30 | | - console.log('Date will continue advancing, creating drift'); |
31 | | - } |
32 | | - |
33 | | - return new Promise(resolve => { |
34 | | - setTimeout(() => { |
35 | | - const actualElapsed = origDateNow() - freezeStartTime; |
36 | | - const drift = actualElapsed; // performance stayed frozen |
37 | | - console.log('Drift created:', drift, 'ms'); |
38 | | - resolve(drift); |
39 | | - }, durationMs); |
| 40 | + console.log('Date.now() advanced by', driftDurationMs, 'ms (total offset:', mockDateOffset, 'ms)'); |
| 41 | + console.log('Drift created:', mockDateOffset, 'ms'); |
| 42 | + |
| 43 | + // Resolve immediately - no actual waiting |
| 44 | + resolve(mockDateOffset); |
40 | 45 | }); |
41 | 46 | }; |
42 | 47 |
|
43 | 48 | // Function to unfreeze (for cleanup between tests) |
44 | 49 | window.unfreezeClocks = function() { |
45 | 50 | if (frozenPerformanceValue !== null) { |
46 | 51 | performance.now = origPerformanceNow; |
| 52 | + Date.now = origDateNow; |
47 | 53 | frozenPerformanceValue = null; |
48 | | - freezeStartTime = null; |
| 54 | + mockDateOffset = 0; |
49 | 55 | console.log('Clocks unfrozen'); |
50 | 56 | } |
51 | 57 | }; |
|
0 commit comments