- Add Next.js app structure with base configs, linting, and formatting - Implement LiveKit Meet page, types, and utility functions - Add Docker, Compose, and deployment scripts for backend and token server - Provide E2E and smoke test scaffolding with Puppeteer and Playwright helpers - Include CSS modules and global styles for UI - Add postMessage and studio integration utilities - Update package.json with dependencies and scripts for development and testing
88 lines
2.9 KiB
TypeScript
88 lines
2.9 KiB
TypeScript
// Vitest setup for broadcast-panel tests
|
|
import { vi } from 'vitest'
|
|
|
|
// Ensure global window exists (jsdom may provide it, but be defensive)
|
|
if (typeof (globalThis as any).window === 'undefined') {
|
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
// @ts-ignore
|
|
(globalThis as any).window = globalThis
|
|
}
|
|
|
|
// polyfill matchMedia for jsdom
|
|
function makeMatchMedia() {
|
|
return (query: string) => {
|
|
return {
|
|
matches: false,
|
|
media: query,
|
|
onchange: null,
|
|
addListener: () => {},
|
|
removeListener: () => {},
|
|
addEventListener: () => {},
|
|
removeEventListener: () => {},
|
|
dispatchEvent: () => false,
|
|
}
|
|
}
|
|
}
|
|
|
|
;(globalThis as any).matchMedia = makeMatchMedia();
|
|
if (typeof (globalThis as any).window !== 'undefined') {
|
|
(globalThis as any).window.matchMedia = makeMatchMedia();
|
|
}
|
|
|
|
// Minimal ResizeObserver polyfill for jsdom
|
|
if (typeof (globalThis as any).ResizeObserver === 'undefined') {
|
|
(globalThis as any).ResizeObserver = class {
|
|
callback: Function;
|
|
constructor(cb: Function) { this.callback = cb }
|
|
observe(_target?: Element) { /* no-op */ }
|
|
unobserve(_target?: Element) { /* no-op */ }
|
|
disconnect() { /* no-op */ }
|
|
} as any;
|
|
}
|
|
|
|
// Partially mock livekit-client to provide a constructible Room while keeping other exports
|
|
vi.mock('livekit-client', () => {
|
|
const instances: any[] = [];
|
|
function Room(this: any, ..._args: any[]) {
|
|
const connect = vi.fn(async (serverUrl?: string, token?: string) => {
|
|
// emulate async connect
|
|
return Promise.resolve();
|
|
});
|
|
const disconnect = vi.fn(() => {});
|
|
const localParticipant = {
|
|
setCameraEnabled: vi.fn(() => Promise.resolve()),
|
|
setMicrophoneEnabled: vi.fn(() => Promise.resolve()),
|
|
};
|
|
const inst = { connect, disconnect, localParticipant, state: 'disconnected', isConnected: false };
|
|
instances.push(inst);
|
|
return inst;
|
|
}
|
|
const Track = { Source: { Camera: 'camera', ScreenShare: 'screen' } };
|
|
return { Room: Room as any, Track, __mocks: { instances } };
|
|
});
|
|
|
|
// Minimal mocks for @livekit/components-react to avoid DOM APIs and hooks during tests
|
|
vi.mock('@livekit/components-react', () => {
|
|
const React = require('react');
|
|
const noop = () => React.createElement('div', null);
|
|
return {
|
|
GridLayout: noop,
|
|
ParticipantTile: noop,
|
|
ControlBar: noop,
|
|
RoomAudioRenderer: noop,
|
|
useTracks: () => [],
|
|
RoomContext: { Provider: ({ children }: any) => children },
|
|
useRoom: () => ({ room: null }),
|
|
useParticipant: () => ({ participant: null }),
|
|
useLocalParticipant: () => ({ localParticipant: null }),
|
|
usePrefetchRoom: () => ({}),
|
|
// export anything else as noop so imports succeed
|
|
};
|
|
});
|
|
|
|
// Mock styles import (no-op)
|
|
vi.mock('@livekit/components-styles', () => ({}));
|
|
|
|
// optional: silence console during tests
|
|
// const orig = console.error; console.error = (...args) => { if (String(args[0]).includes('Warning')) return; orig(...args) }
|