agent-ecosystem/test/renderer/components/team/members/MemberPresenceDot.test.tsx

65 lines
1.9 KiB
TypeScript

import React, { act } from 'react';
import { createRoot } from 'react-dom/client';
import { afterEach, describe, expect, it, vi } from 'vitest';
import { MemberPresenceDot } from '@renderer/components/team/members/MemberPresenceDot';
describe('MemberPresenceDot', () => {
afterEach(() => {
vi.restoreAllMocks();
document.body.innerHTML = '';
});
it('uses a shared wall-clock phase for pulse animations', async () => {
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
const host = document.createElement('div');
document.body.appendChild(host);
const root = createRoot(host);
vi.spyOn(performance, 'now').mockReturnValue(725);
await act(async () => {
root.render(
React.createElement(MemberPresenceDot, {
className: 'size-2.5 bg-emerald-400 animate-pulse',
label: 'ready',
})
);
await Promise.resolve();
});
const dot = host.querySelector('span') as HTMLSpanElement | null;
expect(dot?.style.animationDelay).toBe('-725ms');
expect(dot?.style.animationDuration).toBe('2000ms');
await act(async () => {
root.unmount();
await Promise.resolve();
});
});
it('does not add animation timing to static status dots', async () => {
vi.stubGlobal('IS_REACT_ACT_ENVIRONMENT', true);
const host = document.createElement('div');
document.body.appendChild(host);
const root = createRoot(host);
await act(async () => {
root.render(
React.createElement(MemberPresenceDot, {
className: 'size-2.5 bg-zinc-600',
label: 'offline',
})
);
await Promise.resolve();
});
const dot = host.querySelector('span') as HTMLSpanElement | null;
expect(dot?.style.animationDelay).toBe('');
expect(dot?.style.animationDuration).toBe('');
await act(async () => {
root.unmount();
await Promise.resolve();
});
});
});