diff --git a/packages/playwright-core/src/server/injected/clock.ts b/packages/playwright-core/src/server/injected/clock.ts index 48cc9276a2..414d23b958 100644 --- a/packages/playwright-core/src/server/injected/clock.ts +++ b/packages/playwright-core/src/server/injected/clock.ts @@ -239,7 +239,12 @@ export class ClockController { addTimer(options: { func: TimerHandler, type: TimerType, delay?: number | string, args?: any[] }): number { this._replayLogOnce(); - if (options.func === undefined) + + if (options.type === TimerType.AnimationFrame && !options.func) + throw new Error('Callback must be provided to requestAnimationFrame calls'); + if (options.type === TimerType.IdleCallback && !options.func) + throw new Error('Callback must be provided to requestIdleCallback calls'); + if ([TimerType.Timeout, TimerType.Interval].includes(options.type) && !options.func && options.delay === undefined) throw new Error('Callback must be provided to timer calls'); let delay = options.delay ? +options.delay : 0; diff --git a/tests/library/clock.spec.ts b/tests/library/clock.spec.ts index 90279fd893..daad405e70 100644 --- a/tests/library/clock.spec.ts +++ b/tests/library/clock.spec.ts @@ -75,6 +75,14 @@ it.describe('setTimeout', () => { }).toThrow(); }); + it('does not throw if |undefined| or |null| is passed as a callback', async ({ clock }) => { + const timerId1 = clock.setTimeout(undefined, 10); + const timerId2 = clock.setTimeout(null, 10); + await clock.runFor(10); + expect(timerId1).toBeGreaterThan(0); + expect(timerId2).toBeGreaterThan(timerId1); + }); + it('returns numeric id or object with numeric id', async ({ clock }) => { const result = clock.setTimeout(() => { }, 10); expect(result).toEqual(expect.any(Number)); @@ -761,6 +769,14 @@ it.describe('setInterval', () => { }).toThrow(); }); + it('does not throw if |undefined| or |null| is passed as a callback', async ({ clock }) => { + const timerId1 = clock.setInterval(undefined, 10); + const timerId2 = clock.setInterval(null, 10); + await clock.runFor(10); + expect(timerId1).toBeGreaterThan(0); + expect(timerId2).toBeGreaterThan(timerId1); + }); + it('returns numeric id or object with numeric id', async ({ clock }) => { const result = clock.setInterval(() => {}, 10); expect(result).toBeGreaterThan(0);