mirror of
https://github.com/hanzoai/next.js.git
synced 2026-09-24 17:00:51 +00:00
Refactors some older prefetching tests to be compatible with `clientSegmentCache`. The old tests were too tightly coupled to router implementation details. Some of the ones that don't make sense to convert were removed (for ex, asserting on prefetch cache seeding behavior, or fetch priority of "high", as fetch priority is managed differently with the new router). This refactors the tests to leverage the `act` util from `segment-cache` test suites, and implemented the accordion behavior to more granularly control when prefetches are dispatched. I copied those implementations for now since we don't have a global util for it.
109 lines
3.0 KiB
TypeScript
109 lines
3.0 KiB
TypeScript
export function createTimeController() {
|
|
let fixedTime = Date.now()
|
|
|
|
return {
|
|
install: (browser) => {
|
|
return browser.eval(`
|
|
(() => {
|
|
const OriginalDate = Date;
|
|
const originalSetTimeout = globalThis.setTimeout;
|
|
const originalSetInterval = globalThis.setInterval;
|
|
const originalClearTimeout = globalThis.clearTimeout;
|
|
const originalClearInterval = globalThis.clearInterval;
|
|
|
|
let fixedTime = ${fixedTime};
|
|
let timerIdCounter = 1;
|
|
const timers = new Map();
|
|
|
|
// Override the Date constructor
|
|
globalThis.Date = class extends OriginalDate {
|
|
constructor(...args) {
|
|
if (args.length === 0) {
|
|
super(fixedTime);
|
|
} else {
|
|
super(...args);
|
|
}
|
|
}
|
|
|
|
static now() {
|
|
return fixedTime;
|
|
}
|
|
};
|
|
|
|
// Preserve static methods
|
|
Object.setPrototypeOf(globalThis.Date, OriginalDate);
|
|
|
|
// Override setTimeout
|
|
globalThis.setTimeout = function(callback, delay, ...args) {
|
|
const id = timerIdCounter++;
|
|
timers.set(id, {
|
|
callback,
|
|
args,
|
|
fireTime: fixedTime + (delay || 0),
|
|
interval: false
|
|
});
|
|
return id;
|
|
};
|
|
|
|
// Override setInterval
|
|
globalThis.setInterval = function(callback, delay, ...args) {
|
|
const id = timerIdCounter++;
|
|
timers.set(id, {
|
|
callback,
|
|
args,
|
|
fireTime: fixedTime + (delay || 0),
|
|
interval: true,
|
|
delay: delay || 0
|
|
});
|
|
return id;
|
|
};
|
|
|
|
// Override clearTimeout
|
|
globalThis.clearTimeout = function(id) {
|
|
timers.delete(id);
|
|
};
|
|
|
|
// Override clearInterval
|
|
globalThis.clearInterval = function(id) {
|
|
timers.delete(id);
|
|
};
|
|
|
|
// Add method to advance time
|
|
globalThis.__advanceTime = (ms) => {
|
|
fixedTime += ms;
|
|
|
|
// Fire any timers that should have fired
|
|
const toFire = [];
|
|
for (const [id, timer] of timers.entries()) {
|
|
if (timer.fireTime <= fixedTime) {
|
|
toFire.push({ id, timer });
|
|
}
|
|
}
|
|
|
|
for (const { id, timer } of toFire) {
|
|
try {
|
|
timer.callback(...timer.args);
|
|
} catch (e) {
|
|
console.error('Timer callback error:', e);
|
|
}
|
|
|
|
if (timer.interval) {
|
|
// Reschedule interval timer
|
|
timer.fireTime = fixedTime + timer.delay;
|
|
} else {
|
|
// Remove one-time timer
|
|
timers.delete(id);
|
|
}
|
|
}
|
|
};
|
|
})();
|
|
`)
|
|
},
|
|
|
|
advance: async (browser, ms: number) => {
|
|
fixedTime += ms
|
|
await browser.eval(`globalThis.__advanceTime(${ms})`)
|
|
},
|
|
}
|
|
}
|