fix(ads): pulse a lone banner message through the fade cycle
CI / changes (pull_request) Successful in 2s
CI / unit (pull_request) Successful in 9s
CI / integration (pull_request) Successful in 15s
CI / ui (pull_request) Successful in 49s
CI / gate (pull_request) Successful in 0s
CI / deploy (pull_request) Successful in 57s

A single campaign message (e.g. the default campaign's one message) faded in once
on load and then sat frozen — the rotator only ran the fade/advance cycle when
more than one message existed, so with one message there were no further fades.
Drop the `total > 1` guards: every message now runs the full hold → fade-out →
gap → fade-in cycle, so a lone message pulses (the same message fades back in)
and a lone long message fades at each scroll-loop boundary. Multi-message
rotation is unchanged. Verified by opacity sampling (single message pulses
1→0→gap→0→1 without navigation); the single-message test now asserts the pulse.
This commit is contained in:
Ilia Denisov
2026-06-16 06:39:12 +02:00
parent 9f83962bf7
commit 115c92b39a
2 changed files with 11 additions and 8 deletions
+5 -3
View File
@@ -122,14 +122,16 @@ describe('createBannerRotator', () => {
r.stop();
});
it('shows a single message once and never fades it out', () => {
it('pulses a lone message through the fade cycle (fades out, then back in)', () => {
vi.useFakeTimers();
const { host, calls, shown } = recordingHost(0);
const r = createBannerRotator([{ weight: 1, messages: ['solo'] }], host, cfg);
r.start();
vi.advanceTimersByTime(cfg.fadeInMs + cfg.holdMs * 5);
expect(shown).toEqual(['solo']);
expect(calls).not.toContain('hide');
vi.advanceTimersByTime(cfg.fadeInMs + cfg.holdMs); // hold elapses -> fade out
expect(calls).toContain('hide');
vi.advanceTimersByTime(cfg.fadeOutMs + cfg.gapMs + 1); // -> the same message fades back in
expect(shown).toEqual(['solo', 'solo']);
r.stop();
});