using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Threading;
using System.Windows.Media.Imaging;
using Xunit;
using ytLive.Models;
using ytLive.Services;
namespace ytLive.Tests;
///
/// WebView2Manager owns the frame-driven web sources (composition-captured, see
/// Services/WebCaptureFrameSource.cs). The controller/visual/GraphicCaptureItem
/// layer is WinRT and only exercisable on Windows at runtime, so these tests pin
/// the pure pieces (transparency script, the alpha-bbox math) and the ONE
/// integration test drives the session plumbing with a fake source: registration,
/// crop-stamped frames, the shared cropped preview bitmap, and coalescing to the
/// latest frame.
///
public class WebView2ManagerTests
{
private sealed class FakeWebSource : IScreenCaptureSource
{
public string Key { get; }
public event Action? FrameAvailable;
public FakeWebSource(string key) => Key = key;
public Task StartAsync() => Task.CompletedTask;
public Task StopAsync() => Task.CompletedTask;
public void Pump(VideoFrame frame) => FrameAvailable?.Invoke(frame);
}
// A real Dispatcher pumping on a background STA thread, so the manager's
// BeginInvoke queue can be drained deterministically from the test thread
// (same harness as ScreenCaptureManagerTests).
private sealed class DispatcherPump : IDisposable
{
private readonly Thread _thread;
private readonly ManualResetEventSlim _ready = new(false);
private Dispatcher? _dispatcher;
public Dispatcher Dispatcher => _dispatcher!;
public DispatcherPump()
{
_thread = new Thread(() =>
{
_dispatcher = Dispatcher.CurrentDispatcher;
_ready.Set();
Dispatcher.Run();
});
_thread.IsBackground = true;
_thread.SetApartmentState(ApartmentState.STA);
_thread.Start();
_ready.Wait();
}
// Queued behind anything already posted at Render/higher, so pending
// bitmap copies run first.
public void Drain() => Dispatcher.Invoke(() => { }, DispatcherPriority.ContextIdle);
public void Dispose()
{
Dispatcher.InvokeShutdown();
_thread.Join(3000);
}
}
[Fact]
public void TransparentBackgroundScript_Is_A_Important_Element_Wide_Wipe()
{
// The regression the inline style lost to: a widget repainting a container (or
// html/body) opaque after connect re-backs the capture → "black box" in the
// recording while early frames stayed transparent. The OBS-validated formula is a
// pre-parse