fix: update performance.now() when calling in a busy loop (#35435)
This commit is contained in:
parent
9cb05c56f5
commit
76d5b8778c
|
@ -99,6 +99,7 @@ export class ClockController {
|
||||||
|
|
||||||
now(): number {
|
now(): number {
|
||||||
this._replayLogOnce();
|
this._replayLogOnce();
|
||||||
|
this._syncRealTime();
|
||||||
return this._now.time;
|
return this._now.time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -119,9 +120,21 @@ export class ClockController {
|
||||||
|
|
||||||
performanceNow(): DOMHighResTimeStamp {
|
performanceNow(): DOMHighResTimeStamp {
|
||||||
this._replayLogOnce();
|
this._replayLogOnce();
|
||||||
|
this._syncRealTime();
|
||||||
return this._now.ticks;
|
return this._now.ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _syncRealTime() {
|
||||||
|
if (!this._realTime)
|
||||||
|
return;
|
||||||
|
const now = this._embedder.performanceNow();
|
||||||
|
const sinceLastSync = now - this._realTime.lastSyncTicks;
|
||||||
|
if (sinceLastSync > 0) {
|
||||||
|
this._advanceNow(shiftTicks(this._now.ticks, sinceLastSync));
|
||||||
|
this._realTime.lastSyncTicks = now;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _innerSetTime(time: WallTime) {
|
private _innerSetTime(time: WallTime) {
|
||||||
this._now.time = time;
|
this._now.time = time;
|
||||||
this._now.isFixedTime = false;
|
this._now.isFixedTime = false;
|
||||||
|
@ -216,12 +229,10 @@ export class ClockController {
|
||||||
this._currentRealTimeTimer = {
|
this._currentRealTimeTimer = {
|
||||||
callAt,
|
callAt,
|
||||||
dispose: this._embedder.setTimeout(() => {
|
dispose: this._embedder.setTimeout(() => {
|
||||||
const now = this._embedder.performanceNow();
|
|
||||||
this._currentRealTimeTimer = undefined;
|
this._currentRealTimeTimer = undefined;
|
||||||
const sinceLastSync = now - this._realTime!.lastSyncTicks;
|
this._syncRealTime();
|
||||||
this._realTime!.lastSyncTicks = now;
|
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
void this._runTo(shiftTicks(this._now.ticks, sinceLastSync)).catch(e => console.error(e)).then(() => this._updateRealTimeTimer());
|
void this._runTo(this._now.ticks).catch(e => console.error(e)).then(() => this._updateRealTimeTimer());
|
||||||
}, callAt - this._now.ticks),
|
}, callAt - this._now.ticks),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -231,7 +242,6 @@ export class ClockController {
|
||||||
await this._innerFastForwardTo(shiftTicks(this._now.ticks, ticks | 0));
|
await this._innerFastForwardTo(shiftTicks(this._now.ticks, ticks | 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private async _innerFastForwardTo(to: Ticks) {
|
private async _innerFastForwardTo(to: Ticks) {
|
||||||
if (to < this._now.ticks)
|
if (to < this._now.ticks)
|
||||||
throw new Error('Cannot fast-forward to the past');
|
throw new Error('Cannot fast-forward to the past');
|
||||||
|
|
|
@ -533,3 +533,35 @@ it.describe('Date.now', () => {
|
||||||
expect(dateValue).toBe(1001);
|
expect(dateValue).toBe(1001);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('correctly increments Date.now()/performance.now() during blocking execution', {
|
||||||
|
annotation: {
|
||||||
|
type: 'issue',
|
||||||
|
description: 'https://github.com/microsoft/playwright/issues/35362',
|
||||||
|
}
|
||||||
|
}, async ({ page, server }) => {
|
||||||
|
await page.clock.setSystemTime(new Date('2026-01-01'));
|
||||||
|
server.setRoute('/repro.html', (req, res) => {
|
||||||
|
res.writeHead(200, { 'Content-Type': 'text/html' });
|
||||||
|
res.end(`
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
{
|
||||||
|
const start = performance.now();
|
||||||
|
while (performance.now() - start < 100) { }
|
||||||
|
}
|
||||||
|
{
|
||||||
|
const start = Date.now();
|
||||||
|
while (Date.now() - start < 100) { }
|
||||||
|
}
|
||||||
|
console.log('done');
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
`);
|
||||||
|
});
|
||||||
|
const waitForDone = page.waitForEvent('console', msg => msg.text() === 'done');
|
||||||
|
await page.goto(server.PREFIX + '/repro.html');
|
||||||
|
await waitForDone;
|
||||||
|
});
|
||||||
|
|
Loading…
Reference in New Issue