fix(clock): mock time in Event.prototype.timeStamp (#31986)

Ideally we generate the timestamp when the Event gets created. This
patch adds a best-effort logic, since we can't override the constructor
of natively created events, e.g. `MouseEvent`.

Fixes https://github.com/microsoft/playwright/issues/31924
This commit is contained in:
Max Schmitt 2024-08-02 15:27:54 +02:00 committed by GitHub
parent 878a6a499b
commit d0c840f639
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 21 additions and 0 deletions

View File

@ -31,6 +31,7 @@ The recommended approach is to use `setFixedTime` to set the time to a specific
- `requestIdleCallback`
- `cancelIdleCallback`
- `performance`
- `Event.timeStamp`
:::
## Test with predefined time

View File

@ -697,6 +697,14 @@ export function install(globalObject: WindowOrWorkerGlobalScope, config: Install
(globalObject as any).Intl = api[method]!;
} else if (method === 'performance') {
(globalObject as any).performance = api[method]!;
const kEventTimeStamp = Symbol('playwrightEventTimeStamp');
Object.defineProperty(Event.prototype, 'timeStamp', {
get() {
if (!this[kEventTimeStamp])
this[kEventTimeStamp] = api.performance?.now();
return this[kEventTimeStamp];
}
});
} else {
(globalObject as any)[method] = (...args: any[]) => {
return (api[method] as any).apply(api, args);

View File

@ -1060,6 +1060,18 @@ it.describe('stubTimers', () => {
expect(prev).toBe(0);
});
it('replace Event.prototype.timeStamp', async ({ install }) => {
it.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/31924' });
const clock = install();
await clock.runFor(1000);
const event1 = new Event('foo');
expect(event1.timeStamp).toBe(1000);
await clock.runFor(1000);
const event2 = new Event('foo');
expect(event2.timeStamp).toBe(2000);
expect(event1.timeStamp).toBe(1000);
});
it('uninstalls global performance.now', async ({ install }) => {
const oldNow = performance.now;
const clock = install();