142 lines
4.1 KiB
TypeScript
142 lines
4.1 KiB
TypeScript
/**
|
|
* E2E Test Helpers for Native Mac Tests
|
|
*
|
|
* This module provides helpers for audio round-trip and post-processing tests.
|
|
* It communicates with the Rust backend via Tauri commands exposed for testing.
|
|
*/
|
|
|
|
import { invoke } from '@tauri-apps/api/core';
|
|
import { TauriCommands } from '../src/api/adapters/tauri/constants';
|
|
|
|
/**
|
|
* Test environment information returned by check_test_environment.
|
|
*/
|
|
export interface TestEnvironmentInfo {
|
|
/** Whether any input audio devices are available */
|
|
has_input_devices: boolean;
|
|
/** Whether a virtual audio device (BlackHole, Soundflower) is detected */
|
|
has_virtual_device: boolean;
|
|
/** List of available input device names */
|
|
input_devices: string[];
|
|
/** Whether the gRPC server is connected */
|
|
is_server_connected: boolean;
|
|
/** Whether audio tests can run (has devices + server) */
|
|
can_run_audio_tests: boolean;
|
|
}
|
|
|
|
/**
|
|
* Configuration for test audio injection.
|
|
*/
|
|
export interface TestAudioConfig {
|
|
/** Path to WAV file to inject */
|
|
wav_path: string;
|
|
/** Playback speed multiplier (1.0 = real-time, 2.0 = 2x speed) */
|
|
speed?: number;
|
|
/** Chunk duration in milliseconds */
|
|
chunk_ms?: number;
|
|
}
|
|
|
|
/**
|
|
* Result of test audio injection.
|
|
*/
|
|
export interface TestAudioResult {
|
|
/** Number of chunks sent */
|
|
chunks_sent: number;
|
|
/** Total duration in seconds */
|
|
duration_seconds: number;
|
|
/** Sample rate of the audio */
|
|
sample_rate: number;
|
|
}
|
|
|
|
/**
|
|
* Check if the test environment is properly configured for audio tests.
|
|
*/
|
|
export async function checkTestEnvironment(): Promise<TestEnvironmentInfo> {
|
|
return invoke<TestEnvironmentInfo>(TauriCommands.CHECK_TEST_ENVIRONMENT);
|
|
}
|
|
|
|
/**
|
|
* Inject test audio from a WAV file into the recording stream.
|
|
* This bypasses native audio capture for deterministic testing.
|
|
*
|
|
* @param meetingId - The meeting ID to inject audio into
|
|
* @param config - Audio injection configuration
|
|
*/
|
|
export async function injectTestAudio(
|
|
meetingId: string,
|
|
config: TestAudioConfig
|
|
): Promise<TestAudioResult> {
|
|
return invoke<TestAudioResult>(TauriCommands.INJECT_TEST_AUDIO, {
|
|
meeting_id: meetingId,
|
|
config,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Inject a test tone (sine wave) into the recording stream.
|
|
*
|
|
* @param meetingId - The meeting ID to inject audio into
|
|
* @param frequencyHz - Frequency of the sine wave in Hz
|
|
* @param durationSeconds - Duration of the tone in seconds
|
|
* @param sampleRate - Optional sample rate (default 16000)
|
|
*/
|
|
export async function injectTestTone(
|
|
meetingId: string,
|
|
frequencyHz: number,
|
|
durationSeconds: number,
|
|
sampleRate?: number
|
|
): Promise<TestAudioResult> {
|
|
return invoke<TestAudioResult>(TauriCommands.INJECT_TEST_TONE, {
|
|
meeting_id: meetingId,
|
|
frequency_hz: frequencyHz,
|
|
duration_seconds: durationSeconds,
|
|
sample_rate: sampleRate,
|
|
});
|
|
}
|
|
|
|
/**
|
|
* Test fixture paths for audio files.
|
|
* These paths are relative to the e2e-native-mac directory.
|
|
*/
|
|
export const TestFixtures = {
|
|
/** Path to short test tones (2 seconds) */
|
|
SHORT_TONES: 'fixtures/test-tones-2s.wav',
|
|
/** Path to longer test tones (10 seconds) */
|
|
LONG_TONES: 'fixtures/test-tones-10s.wav',
|
|
/** Path to simple sine wave (440Hz, 2 seconds) */
|
|
SINE_WAVE: 'fixtures/test-sine-440hz-2s.wav',
|
|
} as const;
|
|
|
|
/**
|
|
* Wait for a condition to be true with timeout.
|
|
*/
|
|
export async function waitForCondition(
|
|
condition: () => Promise<boolean> | boolean,
|
|
timeoutMs: number,
|
|
pollIntervalMs: number = 100
|
|
): Promise<boolean> {
|
|
const startTime = Date.now();
|
|
while (Date.now() - startTime < timeoutMs) {
|
|
if (await condition()) {
|
|
return true;
|
|
}
|
|
await new Promise((resolve) => setTimeout(resolve, pollIntervalMs));
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Calculate expected processing time for audio.
|
|
*
|
|
* @param durationSeconds - Audio duration in seconds
|
|
* @param realtimeFactor - Processing speed (1.0 = realtime, 0.5 = 2x faster)
|
|
*/
|
|
export function estimateProcessingTime(
|
|
durationSeconds: number,
|
|
realtimeFactor: number = 0.5
|
|
): number {
|
|
// Base processing time + some buffer
|
|
const baseBuffer = 5; // seconds
|
|
return Math.ceil(durationSeconds * realtimeFactor + baseBuffer);
|
|
}
|