// Copyright HyperTwist, Inc. All Rights Reserved.

#include "Misc/AutomationTest.h"
#include "Misc/FileHelper.h"
#include "Misc/Paths.h"

#include "Blueprint/WidgetTree.h"
#include "Components/TextBlock.h"
#include "HyperTwistBrowser/HyperTwistBrowserBridgeObject.h"
#include "HyperTwistBrowser/HyperTwistBrowserWidget.h"
#include "HyperTwistTraining/HyperTwistCoachDashboardWidget.h"
#include "HyperTwistTraining/HyperTwistTrainingPanelWidget.h"
#include "HyperTwistTraining/HyperTwistTrainingRuntimeLibrary.h"

#if WITH_AUTOMATION_TESTS

namespace HyperTwistBrowserBridgeObjectTestInternal
{
	FHyperTwistTrainingTilingStateEnvelope MakeSampleTilingStateEnvelope()
	{
		FHyperTwistTrainingTilingStateEnvelope Envelope;
		Envelope.SessionId = TEXT("tiling-browser-session-001");
		Envelope.SharedScrambleNotation = TEXT("R, U\nm(3,4)' ; reflect-x");

		FHyperTwistPuzzleState& PuzzleState = Envelope.PuzzleState;
		PuzzleState.Definition.PuzzleId = TEXT("tiling/{3,7}/browser");
		PuzzleState.Definition.PuzzleFamily = EHyperTwistPuzzleFamily::Tiling;
		PuzzleState.Definition.Dimension = 2;
		PuzzleState.Definition.DefinitionVersion = TEXT("2026.06");
		PuzzleState.Definition.NotationProfile = TEXT("magictile-shared");
		PuzzleState.StateEncoding.EncodingProfile = TEXT("tiling-cells/v1");
		PuzzleState.StateEncoding.PayloadJson =
			TEXT("{\"cells\":[\"c0\",\"c1\"],\"selection\":\"face-0\"}");
		PuzzleState.CapturedAtUtc = TEXT("2026-06-19T02:10:00Z");
		PuzzleState.SourceSessionId = Envelope.SessionId;

		FHyperTwistTrainingLiveTimerState& TimerState = Envelope.TimerState;
		TimerState.Phase = EHyperTwistTrainingLiveTimerPhase::Solving;
		TimerState.SolveElapsedMs = 9876;

		return Envelope;
	}

	FString MakeSampleBrowserRuntimeReadyJson(
		const int32 QueuedCommandCountAtRuntimeReady,
		const int32 QueuedShellStateCountAtRuntimeReady
	)
	{
		return FString::Printf(
			TEXT("{\"status\":\"ready\",\"runtime\":\"hypertwist-browser-runtime\",")
			TEXT("\"mode\":\"bundled-module\",\"adapterCount\":21,")
			TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
			TEXT("\"queuedCommandCountAtRuntimeReady\":%d,")
			TEXT("\"queuedShellStateCountAtRuntimeReady\":%d}"),
			QueuedCommandCountAtRuntimeReady,
			QueuedShellStateCountAtRuntimeReady
		);
	}

	FString MakeSampleBrowserRuntimeStatusEnvelopeJson(
		const int32 QueuedCommandCountAtRuntimeReady,
		const int32 QueuedShellStateCountAtRuntimeReady,
		const int32 CommandReceiveCount,
		const int32 ShellStateReceiveCount
	)
	{
		return FString::Printf(
			TEXT("{\"type\":\"browser-runtime-status\",\"source\":\"browser-runtime-shell\",")
			TEXT("\"status\":{\"runtimeStatusId\":\"runtime-ready\",\"runtimeMode\":\"bundled-module\",")
			TEXT("\"bootstrapStartedAtUtc\":\"2026-06-19T04:30:00Z\",")
			TEXT("\"runtimeReadyAtUtc\":\"2026-06-19T04:31:00Z\",")
			TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
			TEXT("\"adapterCount\":21,")
			TEXT("\"queuedCommandCountAtRuntimeReady\":%d,")
			TEXT("\"queuedShellStateCountAtRuntimeReady\":%d,")
			TEXT("\"commandReceiveCount\":%d,")
			TEXT("\"shellStateReceiveCount\":%d,")
			TEXT("\"lastCommandReceivedAtUtc\":\"2026-06-19T04:31:10Z\",")
			TEXT("\"lastShellStateReceivedAtUtc\":\"2026-06-19T04:31:11Z\",")
			TEXT("\"bridgeTrafficStatus\":\"shell-state-live\",")
			TEXT("\"fallbackReason\":null}}"),
			QueuedCommandCountAtRuntimeReady,
			QueuedShellStateCountAtRuntimeReady,
			CommandReceiveCount,
			ShellStateReceiveCount
		);
	}

	void SimulateLiveBrowserRuntimeStatus(
		UHyperTwistBrowserWidget& BrowserWidget,
		const int32 QueuedCommandCountAtRuntimeReady,
		const int32 QueuedShellStateCountAtRuntimeReady,
		const int32 CommandReceiveCount,
		const int32 ShellStateReceiveCount
	)
	{
		BrowserWidget.SetBrowserRuntimeDispatchReadyForTesting(true);
		BrowserWidget.SimulateBrowserRuntimeReadyForTesting(
			MakeSampleBrowserRuntimeReadyJson(
				QueuedCommandCountAtRuntimeReady,
				QueuedShellStateCountAtRuntimeReady
			)
		);
		BrowserWidget.SimulateBrowserEnvelopeForTesting(
			MakeSampleBrowserRuntimeStatusEnvelopeJson(
				QueuedCommandCountAtRuntimeReady,
				QueuedShellStateCountAtRuntimeReady,
				CommandReceiveCount,
				ShellStateReceiveCount
			)
		);
	}

	FHyperTwistTrainingImportedGeneratedModeLaunchRequest MakeSampleGeneratedModeLaunchRequest(
		const FString& RequestSource = TEXT("phase6c-higher-dimensional-launch-surface"),
		const FString& SurfaceId = TEXT("phase6c/magic120cell/generated-mode-surface")
	)
	{
		FHyperTwistTrainingImportedGeneratedModeLaunchRequest Request;
		Request.RequestId = TEXT("generated-launch-request-001");
		Request.RequestedAtUtc = TEXT("2026-06-24T13:55:00Z");
		Request.RequestSource = RequestSource;
		Request.LaunchConfig.DeckId = TEXT("runtime/magic120cell-generated");
		Request.LaunchConfig.UserId = TEXT("local-user");
		Request.LaunchConfig.TrainingSessionId = TEXT("phase6c_launch_sample");
		Request.LaunchConfig.DeliveryMode = EHyperTwistTrainingDeliveryMode::VirtualCube;
		Request.LaunchConfig.PuzzleId = TEXT("polychoron/magic120cell");
		Request.LaunchConfig.SurfaceId = SurfaceId;
		Request.LaunchConfig.SurfaceLabel = TEXT("Magic120Cell generated-mode surface");
		Request.LaunchConfig.RuntimeModeId = TEXT("magic120cell-full-color-runtime-v1");
		Request.LaunchConfig.GeneratorType = TEXT("generated-mode");

		FHyperTwistTrainingImportedRuntimeSelectorChoice ProjectionChoice;
		ProjectionChoice.SelectorId = TEXT("projection");
		ProjectionChoice.SelectorBinding = TEXT("projection");
		ProjectionChoice.SelectedValue = TEXT("4d-projection-distance");
		ProjectionChoice.DisplayValue = TEXT("4D Projection Distance");

		FHyperTwistTrainingImportedRuntimeSelectorChoice SymmetryChoice;
		SymmetryChoice.SelectorId = TEXT("symmetry");
		SymmetryChoice.SelectorBinding = TEXT("symmetry");
		SymmetryChoice.SelectedValue = TEXT("full-puzzle-default-mode");
		SymmetryChoice.DisplayValue = TEXT("Full Puzzle Default");

		FHyperTwistTrainingImportedRuntimeSelectorChoice VisibilityChoice;
		VisibilityChoice.SelectorId = TEXT("visibility");
		VisibilityChoice.SelectorBinding = TEXT("visibility");
		VisibilityChoice.SelectedValue = TEXT("logical-visibility-depth-ladder");
		VisibilityChoice.DisplayValue = TEXT("Logical Visibility Ladder");

		FHyperTwistTrainingImportedRuntimeSelectorChoice FocusChoice;
		FocusChoice.SelectorId = TEXT("focus");
		FocusChoice.SelectorBinding = TEXT("focus");
		FocusChoice.SelectedValue = TEXT("center-cell-recentering");
		FocusChoice.DisplayValue = TEXT("Center Cell Recentering");

		Request.LaunchConfig.SelectorChoices =
		{
			ProjectionChoice,
			SymmetryChoice,
			VisibilityChoice,
			FocusChoice
		};

		return Request;
	}

	UTextBlock* FindDashboardTextBlock(
		UHyperTwistCoachDashboardWidget* CoachDashboard,
		const TCHAR* WidgetName)
	{
		if (CoachDashboard == nullptr)
		{
			return nullptr;
		}

		CoachDashboard->TakeWidget();
		if (CoachDashboard->WidgetTree == nullptr)
		{
			return nullptr;
		}

		return Cast<UTextBlock>(CoachDashboard->WidgetTree->FindWidget(FName(WidgetName)));
	}
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserBridgeObjectNotificationTest,
	"HyperTwist.Browser.Bridge.NotificationCapture",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserBridgeObjectNotificationTest::RunTest(const FString& Parameters)
{
	UHyperTwistBrowserBridgeObject* BridgeObject = NewObject<UHyperTwistBrowserBridgeObject>();
	TestNotNull(TEXT("The browser bridge object must be constructible."), BridgeObject);
	if (BridgeObject == nullptr)
	{
		return false;
	}

	BridgeObject->NotifyEnvelope(TEXT("{\"type\":\"hypertwist-state\"}"));
	BridgeObject->NotifyState(TEXT("{\"phase\":\"1H\"}"));
	BridgeObject->NotifyRuntimeReady(TEXT("{\"status\":\"ready\"}"));

	TestEqual(
		TEXT("The browser bridge object must retain the last envelope payload."),
		BridgeObject->LastEnvelopeJson,
		TEXT("{\"type\":\"hypertwist-state\"}")
	);
	TestEqual(
		TEXT("The browser bridge object must retain the last shell-state payload."),
		BridgeObject->LastStateJson,
		TEXT("{\"phase\":\"1H\"}")
	);
	TestEqual(
		TEXT("The browser bridge object must retain the runtime-ready payload."),
		BridgeObject->LastRuntimeReadyJson,
		TEXT("{\"status\":\"ready\"}")
	);

	BridgeObject->ResetReceivedMessages();
	TestTrue(
		TEXT("Resetting the bridge object must clear all retained payloads."),
		BridgeObject->LastEnvelopeJson.IsEmpty()
			&& BridgeObject->LastStateJson.IsEmpty()
			&& BridgeObject->LastRuntimeReadyJson.IsEmpty()
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserBridgeObjectRuntimeReadyDelegateTest,
	"HyperTwist.Browser.Bridge.RuntimeReadyDelegate",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserBridgeObjectRuntimeReadyDelegateTest::RunTest(const FString& Parameters)
{
	UHyperTwistBrowserBridgeObject* BridgeObject = NewObject<UHyperTwistBrowserBridgeObject>();
	TestNotNull(TEXT("The browser bridge object must be constructible."), BridgeObject);
	if (BridgeObject == nullptr)
	{
		return false;
	}

	int32 RuntimeReadyBroadcastCount = 0;
	FString LastRuntimeReadyPayload;
	const FDelegateHandle DelegateHandle = BridgeObject->OnRuntimeReady.AddLambda(
		[&RuntimeReadyBroadcastCount, &LastRuntimeReadyPayload](const FString& RuntimeReadyJson)
		{
			++RuntimeReadyBroadcastCount;
			LastRuntimeReadyPayload = RuntimeReadyJson;
		}
	);

	BridgeObject->NotifyRuntimeReady(TEXT("{\"status\":\"ready\",\"mode\":\"fallback-js\"}"));

	TestEqual(
		TEXT("Runtime-ready notification must be retained on the bridge object."),
		BridgeObject->LastRuntimeReadyJson,
		TEXT("{\"status\":\"ready\",\"mode\":\"fallback-js\"}")
	);
	TestEqual(
		TEXT("Runtime-ready notification must broadcast once to bridge listeners."),
		RuntimeReadyBroadcastCount,
		1
	);
	TestEqual(
		TEXT("Runtime-ready notification must preserve the broadcast payload."),
		LastRuntimeReadyPayload,
		TEXT("{\"status\":\"ready\",\"mode\":\"fallback-js\"}")
	);

	BridgeObject->OnRuntimeReady.Remove(DelegateHandle);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserBridgeObjectRuntimeReadyPayloadDecodeTest,
	"HyperTwist.Browser.Bridge.RuntimeReadyPayloadDecode",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserBridgeObjectRuntimeReadyPayloadDecodeTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistBrowserBridgeObject* BridgeObject = NewObject<UHyperTwistBrowserBridgeObject>();
	TestNotNull(TEXT("The browser bridge object must be constructible."), BridgeObject);
	if (BridgeObject == nullptr)
	{
		return false;
	}

	const FString RuntimeReadyJson =
		TEXT("{\"status\":\"ready\",\"runtime\":\"hypertwist-browser-runtime\",")
		TEXT("\"mode\":\"bundled-module\",\"adapterCount\":21,")
		TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
		TEXT("\"queuedCommandCountAtRuntimeReady\":2,")
		TEXT("\"queuedShellStateCountAtRuntimeReady\":1}");

	BridgeObject->NotifyRuntimeReady(RuntimeReadyJson);

	FHyperTwistBrowserRuntimeReadyPayload RuntimeReadyPayload;
	TestTrue(
		TEXT("The browser bridge object must decode a typed runtime-ready payload."),
		BridgeObject->TryGetLastRuntimeReadyPayload(RuntimeReadyPayload)
	);
	TestEqual(
		TEXT("The typed runtime-ready payload must preserve the ready status."),
		RuntimeReadyPayload.Status,
		TEXT("ready")
	);
	TestEqual(
		TEXT("The typed runtime-ready payload must preserve the runtime id."),
		RuntimeReadyPayload.Runtime,
		TEXT("hypertwist-browser-runtime")
	);
	TestEqual(
		TEXT("The typed runtime-ready payload must preserve the runtime mode."),
		RuntimeReadyPayload.Mode,
		TEXT("bundled-module")
	);
	TestEqual(
		TEXT("The typed runtime-ready payload must preserve the adapter count."),
		RuntimeReadyPayload.AdapterCount,
		21
	);
	TestEqual(
		TEXT("The typed runtime-ready payload must preserve the queued shell-state count."),
		RuntimeReadyPayload.QueuedShellStateCountAtRuntimeReady,
		1
	);

	BridgeObject->ResetReceivedMessages();
	TestFalse(
		TEXT("Resetting the bridge object must also clear the typed runtime-ready payload cache."),
		BridgeObject->TryGetLastRuntimeReadyPayload(RuntimeReadyPayload)
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserBridgeObjectTilingStateEnvelopeDecodeTest,
	"HyperTwist.Browser.Bridge.TilingStateEnvelopeDecode",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserBridgeObjectTilingStateEnvelopeDecodeTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistBrowserBridgeObject* BridgeObject = NewObject<UHyperTwistBrowserBridgeObject>();
	TestNotNull(TEXT("The browser bridge object must be constructible."), BridgeObject);
	if (BridgeObject == nullptr)
	{
		return false;
	}

	FString EnvelopeJson;
	TestTrue(
		TEXT("The tiling state envelope fixture must serialize through the runtime bridge."),
		UHyperTwistTrainingRuntimeLibrary::TrySerializeBundledTilingStateEnvelopeToJson(
			HyperTwistBrowserBridgeObjectTestInternal::MakeSampleTilingStateEnvelope(),
			EnvelopeJson
		)
	);

	BridgeObject->NotifyEnvelope(EnvelopeJson);
	BridgeObject->NotifyState(EnvelopeJson);

	FHyperTwistTrainingTilingStateEnvelope LastEnvelope;
	TestTrue(
		TEXT("The browser bridge object must decode a typed tiling envelope from envelope transport."),
		BridgeObject->TryGetLastTilingEnvelope(LastEnvelope)
	);
	TestEqual(
		TEXT("The decoded envelope transport must preserve the tiling puzzle definition id."),
		LastEnvelope.PuzzleDefinitionId,
		TEXT("tiling/{3,7}/browser")
	);
	TestEqual(
		TEXT("The decoded envelope transport must normalize the shared scramble notation."),
		LastEnvelope.SharedScrambleNotation,
		TEXT("R U m(3,4)' reflect-x")
	);

	FHyperTwistTrainingTilingStateEnvelope LastStateEnvelope;
	TestTrue(
		TEXT("The browser bridge object must decode a typed tiling envelope from shell-state transport."),
		BridgeObject->TryGetLastTilingStateEnvelope(LastStateEnvelope)
	);
	TestEqual(
		TEXT("The decoded shell-state transport must restore the browser host decision id."),
		LastStateEnvelope.HostDecisionId,
		TEXT("tiling-embedded-browser-host")
	);
	TestEqual(
		TEXT("The decoded shell-state transport must preserve solve elapsed time."),
		LastStateEnvelope.TimerState.SolveElapsedMs,
		9876
	);

	BridgeObject->ResetReceivedMessages();
	TestFalse(
		TEXT("Resetting the bridge object must also clear the typed tiling envelope cache."),
		BridgeObject->TryGetLastTilingEnvelope(LastEnvelope)
			|| BridgeObject->TryGetLastTilingStateEnvelope(LastStateEnvelope)
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserBridgeObjectRuntimeStatusEnvelopeDecodeTest,
	"HyperTwist.Browser.Bridge.RuntimeStatusEnvelopeDecode",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserBridgeObjectRuntimeStatusEnvelopeDecodeTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistBrowserBridgeObject* BridgeObject = NewObject<UHyperTwistBrowserBridgeObject>();
	TestNotNull(TEXT("The browser bridge object must be constructible."), BridgeObject);
	if (BridgeObject == nullptr)
	{
		return false;
	}

	const FString RuntimeStatusEnvelopeJson =
		TEXT("{\"type\":\"browser-runtime-status\",\"source\":\"browser-runtime-shell\",")
		TEXT("\"status\":{\"runtimeStatusId\":\"runtime-ready\",\"runtimeMode\":\"bundled-module\",")
		TEXT("\"bootstrapStartedAtUtc\":\"2026-06-19T04:30:00Z\",")
		TEXT("\"runtimeReadyAtUtc\":\"2026-06-19T04:31:00Z\",")
		TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
		TEXT("\"adapterCount\":21,")
		TEXT("\"queuedCommandCountAtRuntimeReady\":2,")
		TEXT("\"queuedShellStateCountAtRuntimeReady\":1,")
		TEXT("\"commandReceiveCount\":3,")
		TEXT("\"shellStateReceiveCount\":2,")
		TEXT("\"lastCommandReceivedAtUtc\":\"2026-06-19T04:31:10Z\",")
		TEXT("\"lastShellStateReceivedAtUtc\":\"2026-06-19T04:31:11Z\",")
		TEXT("\"bridgeTrafficStatus\":\"shell-state-live\",")
		TEXT("\"fallbackReason\":null}}");

	BridgeObject->NotifyEnvelope(RuntimeStatusEnvelopeJson);

	FHyperTwistBrowserRuntimeStatusEnvelope RuntimeStatusEnvelope;
	TestTrue(
		TEXT("The browser bridge object must decode a typed browser runtime-status envelope."),
		BridgeObject->TryGetLastBrowserRuntimeStatusEnvelope(RuntimeStatusEnvelope)
	);
	TestEqual(
		TEXT("The decoded runtime-status envelope must preserve the envelope type."),
		RuntimeStatusEnvelope.Type,
		TEXT("browser-runtime-status")
	);
	TestEqual(
		TEXT("The decoded runtime-status envelope must preserve the source id."),
		RuntimeStatusEnvelope.Source,
		TEXT("browser-runtime-shell")
	);
	TestEqual(
		TEXT("The decoded runtime-status envelope must preserve the runtime mode."),
		RuntimeStatusEnvelope.Status.RuntimeMode,
		TEXT("bundled-module")
	);
	TestEqual(
		TEXT("The decoded runtime-status envelope must preserve the adapter count."),
		RuntimeStatusEnvelope.Status.AdapterCount,
		21
	);
	TestEqual(
		TEXT("The decoded runtime-status envelope must preserve the bridge traffic status."),
		RuntimeStatusEnvelope.Status.BridgeTrafficStatus,
		TEXT("shell-state-live")
	);

	BridgeObject->NotifyEnvelope(TEXT("{\"type\":\"hypertwist-state\",\"source\":\"browser-runtime-shell\"}"));
	TestTrue(
		TEXT("A non-runtime-status envelope must not clear the last valid runtime-status capture."),
		BridgeObject->TryGetLastBrowserRuntimeStatusEnvelope(RuntimeStatusEnvelope)
	);
	TestEqual(
		TEXT("Retained runtime-status capture must survive later unrelated envelope traffic."),
		RuntimeStatusEnvelope.Status.RuntimeMode,
		TEXT("bundled-module")
	);

	BridgeObject->ResetReceivedMessages();
	TestFalse(
		TEXT("Resetting the bridge object must also clear the typed browser runtime-status cache."),
		BridgeObject->TryGetLastBrowserRuntimeStatusEnvelope(RuntimeStatusEnvelope)
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetQueuedOutboundMessagesTest,
	"HyperTwist.Browser.Widget.QueuedOutboundMessages",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetQueuedOutboundMessagesTest::RunTest(const FString& Parameters)
{
	UHyperTwistBrowserWidget* BrowserWidget = NewObject<UHyperTwistBrowserWidget>();
	TestNotNull(TEXT("The browser widget must be constructible."), BrowserWidget);
	if (BrowserWidget == nullptr)
	{
		return false;
	}

	BrowserWidget->DispatchCommandJson(TEXT("{\"command\":\"alpha\"}"));
	BrowserWidget->PushShellStateJson(TEXT("{\"phase\":\"7A\"}"));
	BrowserWidget->DispatchCommandJson(TEXT("{\"command\":\"beta\"}"));

	TestEqual(
		TEXT("Command payloads must queue while the browser runtime is not ready."),
		BrowserWidget->GetPendingCommandCount(),
		2
	);
	TestTrue(
		TEXT("The last shell-state payload must stay queued while the browser runtime is not ready."),
		BrowserWidget->HasPendingShellStateJson()
	);
	TestFalse(
		TEXT("A fresh browser widget must begin with runtime-ready false."),
		BrowserWidget->IsBrowserRuntimeReady()
	);

	BrowserWidget->SetBrowserRuntimeDispatchReadyForTesting(true);
	BrowserWidget->SimulateBrowserRuntimeReadyForTesting(TEXT("{\"status\":\"ready\"}"));

	TestTrue(
		TEXT("Runtime-ready simulation must mark the browser widget ready."),
		BrowserWidget->IsBrowserRuntimeReady()
	);
	TestEqual(
		TEXT("Queued command payloads must flush when runtime-ready arrives."),
		BrowserWidget->GetPendingCommandCount(),
		0
	);
	TestFalse(
		TEXT("Queued shell-state payload must flush when runtime-ready arrives."),
		BrowserWidget->HasPendingShellStateJson()
	);

	const TArray<FString>& ExecutedScripts = BrowserWidget->GetExecutedBrowserScriptsForTesting();
	TestEqual(
		TEXT("Flushing the queued outbound payloads must execute one shell-state script plus both queued commands."),
		ExecutedScripts.Num(),
		3
	);
	if (ExecutedScripts.Num() == 3)
	{
		TestTrue(
			TEXT("Shell-state must flush before queued commands so the browser runtime sees the latest state first."),
			ExecutedScripts[0].Contains(TEXT("setShellState"))
		);
		TestTrue(
			TEXT("The first queued command must flush through receiveCommand."),
			ExecutedScripts[1].Contains(TEXT("receiveCommand"))
		);
		TestTrue(
			TEXT("The second queued command must also flush through receiveCommand."),
			ExecutedScripts[2].Contains(TEXT("receiveCommand"))
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetBundledShellUrlTest,
	"HyperTwist.Browser.Widget.BundledShellUrl",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetBundledShellUrlTest::RunTest(const FString& Parameters)
{
	const FString BundledShellUrl = UHyperTwistBrowserWidget::ResolveBundledBrowserShellUrl();

	TestFalse(TEXT("The bundled browser shell URL must not be empty."), BundledShellUrl.IsEmpty());
	TestTrue(
		TEXT("The bundled browser shell URL must resolve to a file URL."),
		BundledShellUrl.StartsWith(TEXT("file:///"))
	);
	TestTrue(
		TEXT("The bundled browser shell URL must point at the authoritative Browser shell source."),
		BundledShellUrl.Contains(TEXT("Content/Browser/index.html"))
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetOperatorStatusSurfaceWaitingTest,
	"HyperTwist.Browser.Widget.OperatorStatusSurfaceWaiting",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetOperatorStatusSurfaceWaitingTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistBrowserWidget* BrowserWidget = NewObject<UHyperTwistBrowserWidget>();
	TestNotNull(TEXT("The browser widget must be constructible."), BrowserWidget);
	if (BrowserWidget == nullptr)
	{
		return false;
	}

	BrowserWidget->DispatchCommandJson(TEXT("{\"command\":\"alpha\"}"));
	BrowserWidget->PushShellStateJson(TEXT("{\"phase\":\"8A\"}"));

	const FHyperTwistBrowserOperatorStatusSurface StatusSurface =
		BrowserWidget->GetBrowserOperatorStatusSurface();

	TestTrue(
		TEXT("The native browser operator status surface must stay structurally valid while waiting for runtime-ready."),
		StatusSurface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The waiting surface must advertise the waiting headline."),
		StatusSurface.Headline,
		TEXT("Browser runtime waiting")
	);
	TestEqual(
		TEXT("The waiting surface must preserve the queued command count."),
		StatusSurface.PendingCommandCount,
		1
	);
	TestEqual(
		TEXT("The waiting surface must preserve the queued shell-state count."),
		StatusSurface.PendingShellStateCount,
		1
	);
	TestTrue(
		TEXT("The waiting surface must explain that runtime-ready is still pending."),
		StatusSurface.BridgeStatusLine.Contains(TEXT("waiting for runtime-ready"))
	);
	TestTrue(
		TEXT("The waiting surface must project queue counts for operator review."),
		StatusSurface.QueueStatusLine.Contains(TEXT("commands 1"))
			&& StatusSurface.QueueStatusLine.Contains(TEXT("shell states 1"))
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetOperatorStatusSurfaceLiveTest,
	"HyperTwist.Browser.Widget.OperatorStatusSurfaceLive",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetOperatorStatusSurfaceLiveTest::RunTest(const FString& Parameters)
{
	UHyperTwistBrowserWidget* BrowserWidget = NewObject<UHyperTwistBrowserWidget>();
	TestNotNull(TEXT("The browser widget must be constructible."), BrowserWidget);
	if (BrowserWidget == nullptr)
	{
		return false;
	}

	BrowserWidget->SetBrowserRuntimeDispatchReadyForTesting(true);
	BrowserWidget->SimulateBrowserRuntimeReadyForTesting(
		TEXT("{\"status\":\"ready\",\"runtime\":\"hypertwist-browser-runtime\",")
		TEXT("\"mode\":\"bundled-module\",\"adapterCount\":21,")
		TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
		TEXT("\"queuedCommandCountAtRuntimeReady\":2,")
		TEXT("\"queuedShellStateCountAtRuntimeReady\":1}")
	);

	const FHyperTwistBrowserOperatorStatusSurface ReadyStatusSurface =
		BrowserWidget->GetBrowserOperatorStatusSurface();
	TestEqual(
		TEXT("The operator surface must first expose the runtime-ready stage before live status arrives."),
		ReadyStatusSurface.Headline,
		TEXT("Browser runtime ready")
	);
	TestTrue(
		TEXT("The runtime-ready stage must surface retained startup queue carryover from the typed ready payload."),
		ReadyStatusSurface.QueueStatusLine.Contains(TEXT("commands 2"))
			&& ReadyStatusSurface.QueueStatusLine.Contains(TEXT("shell states 1"))
	);
	TestTrue(
		TEXT("The runtime-ready stage must explain that live runtime-status is still pending."),
		ReadyStatusSurface.BridgeStatusLine.Contains(TEXT("waiting for live runtime-status envelope"))
	);

	BrowserWidget->SimulateBrowserEnvelopeForTesting(
		TEXT("{\"type\":\"browser-runtime-status\",\"source\":\"browser-runtime-shell\",")
		TEXT("\"status\":{\"runtimeStatusId\":\"runtime-ready\",\"runtimeMode\":\"bundled-module\",")
		TEXT("\"bootstrapStartedAtUtc\":\"2026-06-19T04:30:00Z\",")
		TEXT("\"runtimeReadyAtUtc\":\"2026-06-19T04:31:00Z\",")
		TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
		TEXT("\"adapterCount\":21,")
		TEXT("\"queuedCommandCountAtRuntimeReady\":2,")
		TEXT("\"queuedShellStateCountAtRuntimeReady\":1,")
		TEXT("\"commandReceiveCount\":3,")
		TEXT("\"shellStateReceiveCount\":2,")
		TEXT("\"lastCommandReceivedAtUtc\":\"2026-06-19T04:31:10Z\",")
		TEXT("\"lastShellStateReceivedAtUtc\":\"2026-06-19T04:31:11Z\",")
		TEXT("\"bridgeTrafficStatus\":\"shell-state-live\",")
		TEXT("\"fallbackReason\":null}}")
	);

	const FHyperTwistBrowserOperatorStatusSurface StatusSurface =
		BrowserWidget->GetBrowserOperatorStatusSurface();

	TestTrue(
		TEXT("The native browser operator status surface must stay structurally valid once live runtime status is available."),
		StatusSurface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The live surface must advertise the live headline."),
		StatusSurface.Headline,
		TEXT("Browser runtime live")
	);
	TestTrue(
		TEXT("The live surface must report the runtime-ready and runtime-status payloads as present."),
		StatusSurface.bBrowserRuntimeReady
			&& StatusSurface.bHasRuntimeReadyPayload
			&& StatusSurface.bHasRuntimeStatusEnvelope
	);
	TestEqual(
		TEXT("The live surface must preserve the runtime mode."),
		StatusSurface.RuntimeMode,
		TEXT("bundled-module")
	);
	TestEqual(
		TEXT("The live surface must preserve the adapter count."),
		StatusSurface.AdapterCount,
		21
	);
	TestEqual(
		TEXT("The live surface must preserve the browser bootstrap timestamp."),
		StatusSurface.BootstrapStartedAtUtc,
		TEXT("2026-06-19T04:30:00Z")
	);
	TestEqual(
		TEXT("The live surface must preserve the runtime-ready timestamp."),
		StatusSurface.RuntimeReadyAtUtc,
		TEXT("2026-06-19T04:31:00Z")
	);
	TestEqual(
		TEXT("The live surface must preserve the last command receipt timestamp."),
		StatusSurface.LastCommandReceivedAtUtc,
		TEXT("2026-06-19T04:31:10Z")
	);
	TestEqual(
		TEXT("The live surface must preserve the last shell-state receipt timestamp."),
		StatusSurface.LastShellStateReceivedAtUtc,
		TEXT("2026-06-19T04:31:11Z")
	);
	TestTrue(
		TEXT("The live surface must summarize bridge traffic state."),
		StatusSurface.SummaryLine.Contains(TEXT("shell-state-live"))
	);
	TestTrue(
		TEXT("The live surface must surface retained startup queue carryover."),
		StatusSurface.QueueStatusLine.Contains(TEXT("commands 2"))
			&& StatusSurface.QueueStatusLine.Contains(TEXT("shell states 1"))
	);
	TestTrue(
		TEXT("The live surface must surface the command and shell-state receive counts."),
		StatusSurface.BridgeStatusLine.Contains(TEXT("commands 3"))
			&& StatusSurface.BridgeStatusLine.Contains(TEXT("shell states 2"))
	);
	TestTrue(
		TEXT("The live surface must preserve the shell authority line."),
		StatusSurface.ShellAuthorityLine.Contains(TEXT("Content/Browser/index.html"))
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetOperatorStatusSurfaceResetOnShellChangeTest,
	"HyperTwist.Browser.Widget.OperatorStatusSurfaceResetOnShellChange",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetOperatorStatusSurfaceResetOnShellChangeTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistBrowserWidget* BrowserWidget = NewObject<UHyperTwistBrowserWidget>();
	TestNotNull(TEXT("The browser widget must be constructible."), BrowserWidget);
	if (BrowserWidget == nullptr)
	{
		return false;
	}

	BrowserWidget->SetBrowserRuntimeDispatchReadyForTesting(true);
	BrowserWidget->DispatchCommandJson(TEXT("{\"command\":\"alpha\"}"));
	BrowserWidget->PushShellStateJson(TEXT("{\"phase\":\"8A\"}"));
	BrowserWidget->SimulateBrowserRuntimeReadyForTesting(
		TEXT("{\"status\":\"ready\",\"runtime\":\"hypertwist-browser-runtime\",")
		TEXT("\"mode\":\"bundled-module\",\"adapterCount\":21,")
		TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
		TEXT("\"queuedCommandCountAtRuntimeReady\":1,")
		TEXT("\"queuedShellStateCountAtRuntimeReady\":1}")
	);
	BrowserWidget->SimulateBrowserEnvelopeForTesting(
		TEXT("{\"type\":\"browser-runtime-status\",\"source\":\"browser-runtime-shell\",")
		TEXT("\"status\":{\"runtimeStatusId\":\"runtime-ready\",\"runtimeMode\":\"bundled-module\",")
		TEXT("\"bootstrapStartedAtUtc\":\"2026-06-19T04:30:00Z\",")
		TEXT("\"runtimeReadyAtUtc\":\"2026-06-19T04:31:00Z\",")
		TEXT("\"shellAuthority\":\"Content/Browser/index.html\",")
		TEXT("\"adapterCount\":21,")
		TEXT("\"queuedCommandCountAtRuntimeReady\":1,")
		TEXT("\"queuedShellStateCountAtRuntimeReady\":1,")
		TEXT("\"commandReceiveCount\":3,")
		TEXT("\"shellStateReceiveCount\":2,")
		TEXT("\"lastCommandReceivedAtUtc\":\"2026-06-19T04:31:10Z\",")
		TEXT("\"lastShellStateReceivedAtUtc\":\"2026-06-19T04:31:11Z\",")
		TEXT("\"bridgeTrafficStatus\":\"shell-state-live\",")
		TEXT("\"fallbackReason\":null}}")
	);

	const FHyperTwistBrowserOperatorStatusSurface LiveStatusSurface =
		BrowserWidget->GetBrowserOperatorStatusSurface();
	TestEqual(
		TEXT("The setup seam must reach the live operator surface before the reset path is exercised."),
		LiveStatusSurface.Headline,
		TEXT("Browser runtime live")
	);

	BrowserWidget->LoadBrowserUrl(TEXT("https://example.invalid/hypertwist"));

	const FHyperTwistBrowserOperatorStatusSurface ResetStatusSurface =
		BrowserWidget->GetBrowserOperatorStatusSurface();
	TestEqual(
		TEXT("Changing shell authority must reset the operator surface back to waiting."),
		ResetStatusSurface.Headline,
		TEXT("Browser runtime waiting")
	);
	TestFalse(
		TEXT("Changing shell authority must clear retained runtime-ready and runtime-status ownership."),
		ResetStatusSurface.bBrowserRuntimeReady
			|| ResetStatusSurface.bHasRuntimeReadyPayload
			|| ResetStatusSurface.bHasRuntimeStatusEnvelope
	);
	TestTrue(
		TEXT("Changing shell authority must switch the shell authority line to the newly requested shell."),
		ResetStatusSurface.ShellAuthorityLine.Contains(TEXT("https://example.invalid/hypertwist"))
	);
	TestTrue(
		TEXT("Changing shell authority must keep the waiting explanation intact after clearing stale live state."),
		ResetStatusSurface.BridgeStatusLine.Contains(TEXT("waiting for runtime-ready"))
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserTrainingPanelRuntimeInspectSurfaceTest,
	"HyperTwist.Browser.TrainingPanel.RuntimeInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserTrainingPanelRuntimeInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistTrainingPanelWidget* TrainingPanel = NewObject<UHyperTwistTrainingPanelWidget>();
	TestNotNull(TEXT("The training panel widget must be constructible."), TrainingPanel);
	if (TrainingPanel == nullptr)
	{
		return false;
	}

	const FHyperTwistTrainingBrowserRuntimeInspectSurface UnobservedSurface =
		TrainingPanel->GetDisplayedBrowserRuntimeInspectSurface();
	TestFalse(
		TEXT("The training panel browser runtime surface must begin without an observed browser widget."),
		UnobservedSurface.bHasObservedBrowserWidget
	);
	TestTrue(
		TEXT("The unobserved browser runtime surface must explain the missing widget attachment."),
		UnobservedSurface.StatusLine.Contains(TEXT("no observed browser widget"))
	);
	TestTrue(
		TEXT("The unobserved browser runtime surface must preserve a compact summary line."),
		UnobservedSurface.SummaryLine.Contains(TEXT("no observed browser widget"))
	);

	UHyperTwistBrowserWidget* BrowserWidget = NewObject<UHyperTwistBrowserWidget>();
	TestNotNull(TEXT("The observed browser widget must be constructible."), BrowserWidget);
	if (BrowserWidget == nullptr)
	{
		return false;
	}

	TrainingPanel->SetObservedBrowserWidget(BrowserWidget);
	BrowserWidget->DispatchCommandJson(TEXT("{\"command\":\"alpha\"}"));
	BrowserWidget->PushShellStateJson(TEXT("{\"phase\":\"8A\"}"));

	const FHyperTwistTrainingBrowserRuntimeInspectSurface WaitingSurface =
		TrainingPanel->GetDisplayedBrowserRuntimeInspectSurface();
	TestTrue(
		TEXT("The training panel browser runtime surface must acknowledge the observed browser widget."),
		WaitingSurface.bHasObservedBrowserWidget
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must surface the waiting stage before runtime-ready."),
		WaitingSurface.StatusLine.Contains(TEXT("Browser runtime waiting"))
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must preserve the queued outbound counts."),
		WaitingSurface.QueueStatusLine.Contains(TEXT("commands 1"))
			&& WaitingSurface.QueueStatusLine.Contains(TEXT("shell states 1"))
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must preserve the waiting handshake summary."),
		WaitingSurface.SummaryLine.Contains(TEXT("awaiting runtime-ready handshake"))
	);

	HyperTwistBrowserBridgeObjectTestInternal::SimulateLiveBrowserRuntimeStatus(
		*BrowserWidget,
		2,
		1,
		3,
		2
	);

	const FHyperTwistTrainingBrowserRuntimeInspectSurface LiveSurface =
		TrainingPanel->GetDisplayedBrowserRuntimeInspectSurface();
	TestTrue(
		TEXT("The training panel browser runtime surface must remain structurally valid once live runtime status is present."),
		LiveSurface.IsStructurallyValid()
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must surface the live stage."),
		LiveSurface.StatusLine.Contains(TEXT("Browser runtime live"))
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must surface the bridge receive counts in the detail line."),
		LiveSurface.DetailLine.Contains(TEXT("bridge commands 3"))
			&& LiveSurface.DetailLine.Contains(TEXT("shell states 2"))
	);
	TestEqual(
		TEXT("The training panel browser runtime surface must preserve the browser bootstrap timestamp."),
		LiveSurface.BootstrapStartedAtUtc,
		TEXT("2026-06-19T04:30:00Z")
	);
	TestEqual(
		TEXT("The training panel browser runtime surface must preserve the runtime-ready timestamp."),
		LiveSurface.RuntimeReadyAtUtc,
		TEXT("2026-06-19T04:31:00Z")
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must expose the timeline and receipt facts in its detail line."),
		LiveSurface.DetailLine.Contains(TEXT("timeline boot 2026-06-19T04:30:00Z"))
			&& LiveSurface.DetailLine.Contains(TEXT("receipts cmd 2026-06-19T04:31:10Z"))
			&& LiveSurface.DetailLine.Contains(TEXT("shell 2026-06-19T04:31:11Z"))
	);
	TestTrue(
		TEXT("The training panel browser runtime surface must preserve the shell authority line."),
		LiveSurface.ShellAuthorityLine.Contains(TEXT("Content/Browser/index.html"))
	);

	TrainingPanel->ClearObservedBrowserWidget();
	const FHyperTwistTrainingBrowserRuntimeInspectSurface ClearedSurface =
		TrainingPanel->GetDisplayedBrowserRuntimeInspectSurface();
	TestFalse(
		TEXT("Clearing the observed browser widget must return the panel to the unobserved browser runtime state."),
		ClearedSurface.bHasObservedBrowserWidget
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserCoachDashboardRuntimeInspectSurfaceTest,
	"HyperTwist.Browser.CoachDashboard.RuntimeInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserCoachDashboardRuntimeInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject<UHyperTwistCoachDashboardWidget>();
	TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard);
	if (CoachDashboard == nullptr)
	{
		return false;
	}

	UHyperTwistBrowserWidget* BrowserWidget = NewObject<UHyperTwistBrowserWidget>();
	TestNotNull(TEXT("The observed browser widget must be constructible."), BrowserWidget);
	if (BrowserWidget == nullptr)
	{
		return false;
	}

	CoachDashboard->SetObservedBrowserWidget(BrowserWidget);

	BrowserWidget->DispatchCommandJson(TEXT("{\"command\":\"alpha\"}"));
	BrowserWidget->PushShellStateJson(TEXT("{\"phase\":\"8A\"}"));
	const FHyperTwistTrainingBrowserRuntimeInspectSurface WaitingSurface =
		CoachDashboard->GetDisplayedBrowserRuntimeInspectSurface();
	TestEqual(
		TEXT("The coach dashboard browser runtime inspect surface must always expose the diagnostics headline."),
		WaitingSurface.Headline,
		TEXT("Browser runtime diagnostics")
	);
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must surface the waiting stage even before a presentation refresh."),
		WaitingSurface.StatusLine.Contains(TEXT("Browser runtime waiting"))
	);
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must preserve the waiting handshake summary."),
		WaitingSurface.SummaryLine.Contains(TEXT("awaiting runtime-ready handshake"))
	);

	HyperTwistBrowserBridgeObjectTestInternal::SimulateLiveBrowserRuntimeStatus(
		*BrowserWidget,
		2,
		1,
		3,
		2
	);

	const FHyperTwistTrainingBrowserRuntimeInspectSurface LiveInspectSurface =
		CoachDashboard->GetDisplayedBrowserRuntimeInspectSurface();
	TestEqual(
		TEXT("The coach dashboard browser runtime inspect surface must expose the diagnostics headline."),
		LiveInspectSurface.Headline,
		TEXT("Browser runtime diagnostics")
	);
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must project the live browser runtime stage before a presentation refresh."),
		LiveInspectSurface.StatusLine.Contains(TEXT("Browser runtime live"))
	);
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must preserve the live bridge summary."),
		LiveInspectSurface.SummaryLine.Contains(TEXT("shell-state-live"))
	);

	CoachDashboard->RefreshCoachDashboardView();

	const FHyperTwistTrainingBrowserRuntimeInspectSurface BrowserRuntimeSurface =
		CoachDashboard->GetDisplayedBrowserRuntimeInspectSurface();
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must carry the bridge detail line through the dashboard presentation."),
		BrowserRuntimeSurface.DetailLine.Contains(TEXT("bridge commands 3"))
			&& BrowserRuntimeSurface.DetailLine.Contains(TEXT("runtime-status envelope yes"))
	);
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must retain shell authority visibility."),
		BrowserRuntimeSurface.DetailLine.Contains(TEXT("Content/Browser/index.html"))
	);
	TestTrue(
		TEXT("The coach dashboard browser runtime inspect surface must carry the runtime timeline and receipt facts through the dashboard presentation."),
		BrowserRuntimeSurface.DetailLine.Contains(TEXT("timeline boot 2026-06-19T04:30:00Z"))
			&& BrowserRuntimeSurface.DetailLine.Contains(TEXT("receipts cmd 2026-06-19T04:31:10Z"))
			&& BrowserRuntimeSurface.DetailLine.Contains(TEXT("shell 2026-06-19T04:31:11Z"))
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistTrainingPanelControlInputReadinessInspectSurfaceTest,
	"HyperTwist.Browser.TrainingPanel.ControlInputReadinessInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistTrainingPanelControlInputReadinessInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistTrainingPanelWidget* TrainingPanel = NewObject<UHyperTwistTrainingPanelWidget>();
	TestNotNull(TEXT("The training panel widget must be constructible."), TrainingPanel);
	if (TrainingPanel == nullptr)
	{
		return false;
	}

	const FHyperTwistTrainingControlInputReadinessInspectSurface Surface =
		TrainingPanel->GetDisplayedControlInputReadinessInspectSurface();
	TestTrue(
		TEXT("The control/input readiness surface must be structurally valid."),
		Surface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The control/input readiness surface must keep a stable headline."),
		Surface.Headline,
		TEXT("Control and input readiness")
	);
	TestEqual(
		TEXT("The control/input readiness surface must expose the shipped classic keyboard profile."),
		Surface.KeyboardProfileName,
		TEXT("classic-wca-keyboard/v1")
	);
	TestTrue(
		TEXT("The control/input readiness surface must report the shipped classic cube mouse/touch/shortcut lane."),
		Surface.bClassicCubeMouseInputReady
			&& Surface.bClassicCubeTouchInputReady
			&& Surface.bClassicCubeShortcutReady
	);
	TestTrue(
		TEXT("The control/input readiness surface must spell out the shipped classic cube pointer roster."),
		Surface.ClassicCubePointerLine.Contains(TEXT("LMB clockwise"))
			&& Surface.ClassicCubePointerLine.Contains(TEXT("RMB counter-clockwise"))
			&& Surface.ClassicCubePointerLine.Contains(TEXT("touch clockwise"))
			&& Surface.ClassicCubePointerLine.Contains(TEXT("MMB drag orbit"))
			&& Surface.ClassicCubePointerLine.Contains(TEXT("wheel zoom"))
	);
	TestTrue(
		TEXT("The control/input readiness surface must spell out the shipped classic cube action shortcuts."),
		Surface.ClassicCubeActionShortcutLine.Contains(TEXT("R scramble"))
			&& Surface.ClassicCubeActionShortcutLine.Contains(TEXT("Enter submit"))
			&& Surface.ClassicCubeActionShortcutLine.Contains(TEXT("V hold-to-talk"))
			&& Surface.ClassicCubeActionShortcutLine.Contains(TEXT("C cycle voice"))
	);
	TestTrue(
		TEXT("The control/input readiness surface must report the higher-dimensional keyboard lane and explicit dedicated-family runtime ownership for both shipped families."),
		Surface.bHigherDimensionalKeyboardInputReady
			&& Surface.bHigherDimensionalDedicatedFamilyReady
	);
	TestTrue(
		TEXT("The control/input readiness surface must name the concrete Magic120Cell and MagicCube5D runtime ownership surfaces instead of only reporting broad catalog validity."),
		Surface.HigherDimensionalStatusLine.Contains(TEXT("magic120cell-cleanroom-runtime-activation"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/runtime-host-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/dedicated-training-view-context-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/dedicated-training-session-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magic120cell/interactive-scene-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("magiccube5d-cleanroom-runtime-activation"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/runtime-host-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/dedicated-training-view-context-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/dedicated-training-session-surface"))
			&& Surface.HigherDimensionalStatusLine.Contains(TEXT("phase6c/magiccube5d/interactive-scene-surface"))
	);
	TestTrue(
		TEXT("The control/input readiness surface must report the current project-level input groundwork."),
		Surface.bEnhancedInputProjectGroundworkPresent
			&& Surface.bMotionControllerGroundworkPresent
			&& Surface.bImmersivePresenceContractReady
	);
	TestTrue(
		TEXT("The control/input readiness surface must keep the current project OpenXR plugin posture explicit."),
		Surface.bOpenXrProjectPluginEnabled
			&& Surface.bXrVerticalAdjustmentAxisPresent
	);
	TestFalse(
		TEXT("The control/input readiness surface must keep unfinished XR/runtime and preferences truth explicit."),
		Surface.bFinishedXrRuntimeReady || Surface.bFinishedPreferencesReady
	);
		TestTrue(
			TEXT("The control/input readiness surface must expose the bounded XR runtime owner, preference profile, controller binding profile, and controller settings ownership surface."),
			Surface.bBoundedXrRuntimeOwnerReady
				&& Surface.bXrPreferenceProfileReady
				&& Surface.bXrControllerBindingProfileReady
				&& Surface.bXrControllerSettingsOwnershipReady
				&& Surface.bXrControllerRebindingOwnershipReady
				&& Surface.XrRuntimeOwnerId == TEXT("xr/openxr-desktop-training-runtime-owner")
				&& Surface.XrPreferenceProfileId == TEXT("xr-openxr-training-preferences/v1")
				&& Surface.XrControllerBindingProfileId == TEXT("xr-openxr-motion-controllers/v1")
				&& Surface.XrControllerSettingsOwnerId
					== TEXT("xr-openxr-controller-settings-owner/v1")
				&& Surface.XrControllerRebindingSurfaceId
					== TEXT("xr-openxr-controller-rebinding-surface/v1")
				&& Surface.XrDefaultControllerLayoutPresetId
					== TEXT("xr-openxr-controller-layout-default/v1")
				&& Surface.XrPreferenceFieldCount == 8
				&& Surface.XrControllerBindingAxisCount == 8
				&& Surface.XrSupportedControllerFamilyCount == 4
				&& Surface.XrControllerSettingsFieldCount == 8
				&& Surface.XrControllerRebindableInputCount == 12
				&& Surface.XrControllerLayoutPresetCount == 3
				&& !Surface.bWindowsPackagedControllerProofReady
		);
	TestTrue(
		TEXT("The control/input readiness surface must now expose bounded non-XR preferences continuity for camera export and immersive session recall."),
		Surface.PreferencesStatusLine.Contains(TEXT("artifact/camera-export-json"))
			&& Surface.PreferencesStatusLine.Contains(TEXT("immersive-training-session-recall-boundary"))
			&& Surface.PreferencesStatusLine.Contains(TEXT("recall scopes 3"))
			&& Surface.PreferencesStatusLine.Contains(TEXT("preference fields 5"))
	);
	TestEqual(
		TEXT("The control/input readiness surface must expose a stable structured XR host decision id."),
		Surface.XrHostDecisionId,
		TEXT("desktop-hosted-openxr-controller-widening-no-go")
	);
	TestTrue(
		TEXT("The control/input readiness surface must keep the No-Go decision and reopen requirements explicit in structured form."),
		Surface.bNativeOpenXrControllerWideningNoGo
			&& Surface.bRequiresDedicatedRuntimeOwnersForReopen
			&& Surface.bRequiresUserFacingSettingsRebindingForReopen
			&& Surface.bRequiresWindowsPackagedControllerValidationForReopen
	);
		TestTrue(
			TEXT("The control/input readiness surface must say plainly that controller settings/rebinding are owned while packaged controller proof is not yet shipped."),
			Surface.XrStatusLine.Contains(TEXT("not yet shipped"))
				&& Surface.XrStatusLine.Contains(TEXT("OpenXR project plugin yes"))
				&& Surface.XrStatusLine.Contains(TEXT("vertical adjust axis yes"))
				&& Surface.XrStatusLine.Contains(TEXT("xr/openxr-desktop-training-runtime-owner"))
				&& Surface.XrStatusLine.Contains(TEXT("xr-openxr-motion-controllers/v1"))
				&& Surface.XrStatusLine.Contains(TEXT("xr-openxr-controller-settings-owner/v1"))
		);
	TestTrue(
		TEXT("The control/input readiness surface must now spell out the bounded vertical-adjust and pointer preference ownership."),
		Surface.XrPreferenceOwnerLine.Contains(TEXT("vertical adjust 120"))
			&& Surface.XrPreferenceOwnerLine.Contains(TEXT("pointer 180"))
	);
		TestTrue(
			TEXT("The control/input readiness surface must retain the fixed No-Go host decision and the remaining packaged-controller validation gap."),
			Surface.NextPacketLine.Contains(TEXT("No-Go"))
				&& Surface.NextPacketLine.Contains(TEXT("packaged controller validation"))
		);
		TestTrue(
			TEXT("The control/input readiness detail line must surface the fixed No-Go host decision operators actually need to see."),
			Surface.DetailLine.Contains(TEXT("No-Go"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-training-preferences/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-motion-controllers/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-settings-owner/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-rebinding-surface/v1"))
		);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoachDashboardControlInputReadinessInspectSurfaceTest,
	"HyperTwist.Browser.CoachDashboard.ControlInputReadinessInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoachDashboardControlInputReadinessInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject<UHyperTwistCoachDashboardWidget>();
	TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard);
	if (CoachDashboard == nullptr)
	{
		return false;
	}

	CoachDashboard->RefreshCoachDashboardView();
	const FHyperTwistTrainingControlInputReadinessInspectSurface Surface =
		CoachDashboard->GetDisplayedControlInputReadinessInspectSurface();
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must stay structurally valid after a view refresh."),
		Surface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The coach dashboard control/input readiness surface must preserve the diagnostics headline."),
		Surface.Headline,
		TEXT("Control and input readiness")
	);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must retain the keyboard profile fact in its detail line."),
		Surface.DetailLine.Contains(TEXT("classic-wca-keyboard/v1"))
	);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must retain the concrete higher-dimensional family ownership ids in its detail line."),
		Surface.DetailLine.Contains(TEXT("phase6c/magic120cell/runtime-host-surface"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magiccube5d/interactive-scene-surface"))
	);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must retain the exact classic cube pointer and action rosters in its detail line."),
		Surface.DetailLine.Contains(TEXT("LMB clockwise"))
			&& Surface.DetailLine.Contains(TEXT("MMB drag orbit"))
			&& Surface.DetailLine.Contains(TEXT("wheel zoom"))
			&& Surface.DetailLine.Contains(TEXT("R scramble"))
			&& Surface.DetailLine.Contains(TEXT("V hold-to-talk"))
	);
		TestTrue(
			TEXT("The coach dashboard control/input readiness surface must retain the packaged-proof gap and controller-settings ownership truth in its detail line."),
			Surface.DetailLine.Contains(TEXT("not yet shipped"))
				&& Surface.DetailLine.Contains(TEXT("OpenXR project plugin yes"))
				&& Surface.DetailLine.Contains(TEXT("vertical adjust axis yes"))
				&& Surface.DetailLine.Contains(TEXT("xr/openxr-desktop-training-runtime-owner"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-settings-owner/v1"))
		);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must retain the bounded non-XR preferences continuity ids in its detail line."),
		Surface.DetailLine.Contains(TEXT("artifact/camera-export-json"))
			&& Surface.DetailLine.Contains(TEXT("immersive-training-session-recall-boundary"))
	);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must preserve the explicit enabled OpenXR project plugin truth."),
		Surface.bOpenXrProjectPluginEnabled
			&& Surface.bXrVerticalAdjustmentAxisPresent
	);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must retain the bounded vertical-adjust and pointer preference ownership."),
		Surface.DetailLine.Contains(TEXT("vertical adjust 120"))
			&& Surface.DetailLine.Contains(TEXT("pointer 180"))
	);
		TestTrue(
			TEXT("The coach dashboard control/input readiness surface must expose the bounded XR runtime owner, preference profile, controller binding profile, and controller settings ownership surface."),
			Surface.bBoundedXrRuntimeOwnerReady
				&& Surface.bXrPreferenceProfileReady
				&& Surface.bXrControllerBindingProfileReady
				&& Surface.bXrControllerSettingsOwnershipReady
				&& Surface.bXrControllerRebindingOwnershipReady
				&& Surface.XrRuntimeOwnerId == TEXT("xr/openxr-desktop-training-runtime-owner")
				&& Surface.XrPreferenceProfileId == TEXT("xr-openxr-training-preferences/v1")
				&& Surface.XrControllerBindingProfileId == TEXT("xr-openxr-motion-controllers/v1")
				&& Surface.XrControllerSettingsOwnerId
					== TEXT("xr-openxr-controller-settings-owner/v1")
				&& Surface.XrControllerRebindingSurfaceId
					== TEXT("xr-openxr-controller-rebinding-surface/v1")
				&& Surface.XrPreferenceFieldCount == 8
				&& Surface.XrControllerBindingAxisCount == 8
				&& Surface.XrSupportedControllerFamilyCount == 4
				&& Surface.XrControllerSettingsFieldCount == 8
				&& Surface.XrControllerRebindableInputCount == 12
				&& Surface.XrControllerLayoutPresetCount == 3
				&& !Surface.bWindowsPackagedControllerProofReady
		);
	TestEqual(
		TEXT("The coach dashboard control/input readiness surface must preserve the structured XR host decision id."),
		Surface.XrHostDecisionId,
		TEXT("desktop-hosted-openxr-controller-widening-no-go")
	);
	TestTrue(
		TEXT("The coach dashboard control/input readiness surface must preserve the structured No-Go decision and reopen requirements."),
		Surface.bNativeOpenXrControllerWideningNoGo
			&& Surface.bRequiresDedicatedRuntimeOwnersForReopen
			&& Surface.bRequiresUserFacingSettingsRebindingForReopen
			&& Surface.bRequiresWindowsPackagedControllerValidationForReopen
	);
		TestTrue(
			TEXT("The coach dashboard control/input readiness surface must keep the fixed No-Go host decision visible in its rendered detail line."),
			Surface.DetailLine.Contains(TEXT("No-Go"))
				&& Surface.DetailLine.Contains(TEXT("packaged controller validation"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-motion-controllers/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-rebinding-surface/v1"))
		);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistTrainingPanelControlSettingsOwnershipInspectSurfaceTest,
	"HyperTwist.Browser.TrainingPanel.ControlSettingsOwnershipInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistTrainingPanelControlSettingsOwnershipInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistTrainingPanelWidget* TrainingPanel = NewObject<UHyperTwistTrainingPanelWidget>();
	TestNotNull(TEXT("The training panel widget must be constructible."), TrainingPanel);
	if (TrainingPanel == nullptr)
	{
		return false;
	}

	const FHyperTwistTrainingControlSettingsOwnershipInspectSurface Surface =
		TrainingPanel->GetDisplayedControlSettingsOwnershipInspectSurface();
	TestTrue(
		TEXT("The control settings ownership surface must be structurally valid."),
		Surface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The control settings ownership surface must keep a stable headline."),
		Surface.Headline,
		TEXT("Control settings ownership")
	);
	TestTrue(
		TEXT("The control settings ownership surface must report the shipped first-party camera, immersive, dedicated-family, and selector ownership lanes."),
		Surface.bCameraSettingsReady
			&& Surface.bImmersivePresenceSettingsReady
			&& Surface.bMagic120CellViewSettingsReady
			&& Surface.bMagicCube5DViewSettingsReady
			&& Surface.bHigherDimensionalSelectorSettingsReady
	);
	TestTrue(
		TEXT("The control settings ownership surface must now expose first-party XR/controller rebinding ownership explicitly while keeping finished packaged proof false."),
		!Surface.bFinishedControllerRebindingReady
			&& Surface.bXrControllerSettingsOwnershipReady
			&& Surface.bXrControllerRebindingOwnershipReady
			&& !Surface.bWindowsPackagedControllerProofReady
	);
	TestTrue(
		TEXT("The control settings ownership surface must keep the current enabled OpenXR project plugin posture explicit."),
		Surface.bOpenXrProjectPluginEnabled
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose a stable structured XR host decision id."),
		Surface.XrHostDecisionId,
		TEXT("desktop-hosted-openxr-controller-widening-no-go")
	);
	TestTrue(
		TEXT("The control settings ownership surface must keep the No-Go decision and reopen requirements explicit in structured form."),
		Surface.bNativeOpenXrControllerWideningNoGo
			&& Surface.bRequiresDedicatedRuntimeOwnersForReopen
			&& Surface.bRequiresUserFacingSettingsRebindingForReopen
			&& Surface.bRequiresWindowsPackagedControllerValidationForReopen
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the shipped camera settings tool id."),
		Surface.CameraSettingsToolId,
		TEXT("tool/camera-settings")
	);
	TestTrue(
		TEXT("The control settings ownership surface must expose camera continuity through the shipped camera-export artifact and structured viewer tags."),
		Surface.bCameraSettingsContinuityReady
			&& Surface.CameraSettingsExportArtifactId == TEXT("artifact/camera-export-json")
			&& Surface.CameraSettingsWorkflowTagCount == 3
			&& Surface.CameraSettingsPreviewStateTagCount == 2
			&& Surface.CameraSettingsExportArtifactCount == 1
	);
	TestTrue(
		TEXT("The control settings ownership surface must expose immersive session-local continuity through the shipped recall boundary and structured preference counts."),
		Surface.bImmersiveSessionRecallReady
			&& Surface.ImmersivePresenceContractId
				== TEXT("immersive-training-presence-control-contract")
			&& Surface.ImmersiveSessionRecallBoundaryId
				== TEXT("immersive-training-session-recall-boundary")
			&& Surface.ImmersivePresenceSurfaceTagCount == 4
			&& Surface.ImmersiveSessionRecallScopeCount == 3
			&& Surface.ImmersiveSessionRecallPreferenceFieldTagCount == 5
			&& Surface.ImmersiveSessionRecallResetSurfaceTagCount == 3
	);
		TestTrue(
			TEXT("The control settings ownership surface must expose the bounded XR preference, controller-profile, and controller-settings ownership packet."),
			Surface.bXrPreferenceProfileReady
				&& Surface.bXrControllerBindingProfileReady
				&& Surface.bXrControllerSettingsOwnershipReady
				&& Surface.bXrControllerRebindingOwnershipReady
				&& Surface.XrRuntimeOwnerId == TEXT("xr/openxr-desktop-training-runtime-owner")
				&& Surface.XrPreferenceProfileId == TEXT("xr-openxr-training-preferences/v1")
				&& Surface.XrControllerBindingProfileId == TEXT("xr-openxr-motion-controllers/v1")
				&& Surface.XrControllerSettingsOwnerId
					== TEXT("xr-openxr-controller-settings-owner/v1")
				&& Surface.XrControllerRebindingSurfaceId
					== TEXT("xr-openxr-controller-rebinding-surface/v1")
				&& Surface.XrDefaultControllerLayoutPresetId
					== TEXT("xr-openxr-controller-layout-default/v1")
				&& Surface.XrPreferenceFieldCount == 8
				&& Surface.XrControllerBindingAxisCount == 8
				&& Surface.XrSupportedControllerFamilyCount == 4
				&& Surface.XrControllerSettingsFieldCount == 8
				&& Surface.XrControllerRebindableInputCount == 12
				&& Surface.XrControllerLayoutPresetCount == 3
		);
	TestEqual(
		TEXT("The control settings ownership surface must keep the default active higher-dimensional view context explicit when no live session is attached."),
		Surface.ActiveHigherDimensionalViewContextId,
		TEXT("none")
	);
	TestEqual(
		TEXT("The control settings ownership surface must keep the default active higher-dimensional session surface explicit when no live session is attached."),
		Surface.ActiveHigherDimensionalSessionSurfaceId,
		TEXT("none")
	);
	TestEqual(
		TEXT("The control settings ownership surface must keep the default active higher-dimensional interactive scene explicit when no live session is attached."),
		Surface.ActiveHigherDimensionalInteractiveSceneSurfaceId,
		TEXT("none")
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the shipped Magic120Cell view profile contract id."),
		Surface.Magic120CellViewProfileContractId,
		TEXT("magic120cell-focus-view-profile")
	);
	TestTrue(
		TEXT("The control settings ownership surface must expose shipped Magic120Cell persistence ownership as real structured state."),
		Surface.bMagic120CellPersistenceSettingsReady
			&& Surface.Magic120CellSessionSurfaceId
				== TEXT("phase6c/magic120cell/dedicated-training-session-surface")
			&& Surface.Magic120CellSceneSurfaceId
				== TEXT("phase6c/magic120cell/interactive-scene-surface")
			&& Surface.Magic120CellPersistenceBoundaryId
				== TEXT("magic120cell-persistence-boundary")
			&& Surface.Magic120CellStateSemanticsId
				== TEXT("phase6c/magic120cell/family-owned-scene-state")
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current Magic120Cell projection-tag count."),
		Surface.Magic120CellProjectionSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current Magic120Cell symmetry-preset count."),
		Surface.Magic120CellSymmetryPresetTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current Magic120Cell visibility-preset count."),
		Surface.Magic120CellVisibilityPresetTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current Magic120Cell focus-surface count."),
		Surface.Magic120CellFocusSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the shipped MagicCube5D view profile contract id."),
		Surface.MagicCube5DViewProfileContractId,
		TEXT("magiccube5d-projection-view-profile")
	);
	TestTrue(
		TEXT("The control settings ownership surface must expose shipped MagicCube5D persistence ownership as real structured state."),
		Surface.bMagicCube5DPersistenceSettingsReady
			&& Surface.MagicCube5DSessionSurfaceId
				== TEXT("phase6c/magiccube5d/dedicated-training-session-surface")
			&& Surface.MagicCube5DSceneSurfaceId
				== TEXT("phase6c/magiccube5d/interactive-scene-surface")
			&& Surface.MagicCube5DPersistenceBoundaryId
				== TEXT("magiccube5d-persistence-boundary")
			&& Surface.MagicCube5DStateSemanticsId
				== TEXT("phase6c/magiccube5d/family-owned-scene-state")
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current MagicCube5D projection-tag count."),
		Surface.MagicCube5DProjectionSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current MagicCube5D stereo-tag count."),
		Surface.MagicCube5DStereoSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current MagicCube5D visibility-tag count."),
		Surface.MagicCube5DVisibilitySurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current MagicCube5D focus-surface count."),
		Surface.MagicCube5DFocusSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current Magic120Cell selector count."),
		Surface.Magic120CellSelectorCount,
		4
	);
	TestEqual(
		TEXT("The control settings ownership surface must expose the current MagicCube5D selector count."),
		Surface.MagicCube5DSelectorCount,
		4
	);
		TestTrue(
			TEXT("The control settings ownership surface must say plainly that XR/controller rebinding is first-party-owned while packaged proof is not yet shipped."),
			Surface.DetailLine.Contains(TEXT("not yet shipped"))
				&& Surface.DetailLine.Contains(TEXT("project OpenXR plugin enabled"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-training-preferences/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-settings-owner/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-rebinding-surface/v1"))
		);
	TestTrue(
		TEXT("The control settings ownership surface must keep the fixed desktop-hosted No-Go posture visible."),
		Surface.DetailLine.Contains(TEXT("No-Go"))
	);
	TestTrue(
		TEXT("The control settings ownership surface must retain the camera settings tool reference in its detail line."),
		Surface.DetailLine.Contains(TEXT("tool/camera-settings"))
	);
	TestTrue(
		TEXT("The control settings ownership surface must retain the shipped camera-export and immersive session-recall ids in its detail line."),
		Surface.DetailLine.Contains(TEXT("artifact/camera-export-json"))
			&& Surface.DetailLine.Contains(TEXT("immersive-training-session-recall-boundary"))
	);
	TestTrue(
		TEXT("The control settings ownership surface detail line must now keep dedicated family session, scene, persistence, and state-semantics ids visible."),
		Surface.DetailLine.Contains(TEXT("phase6c/magic120cell/dedicated-training-session-surface"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magic120cell/interactive-scene-surface"))
			&& Surface.DetailLine.Contains(TEXT("magic120cell-persistence-boundary"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magic120cell/family-owned-scene-state"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magiccube5d/dedicated-training-session-surface"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magiccube5d/interactive-scene-surface"))
			&& Surface.DetailLine.Contains(TEXT("magiccube5d-persistence-boundary"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magiccube5d/family-owned-scene-state"))
	);
	TestFalse(
		TEXT("The control settings ownership surface must not fabricate repository-backed selector recall before a launch request has been observed."),
		Surface.bRepositoryBackedSelectorRecallReady
	);
	TestTrue(
		TEXT("The control settings ownership surface must explain when repository-backed selector recall is unavailable."),
		Surface.SelectorRecallLine.Contains(TEXT("unavailable"))
	);

	TrainingPanel->CachedImportedGeneratedModeLaunchRequest =
		HyperTwistBrowserBridgeObjectTestInternal::MakeSampleGeneratedModeLaunchRequest(
			TEXT("runtime-imported-generated-mode"),
			TEXT("phase6c/imported-generated-mode-surface")
		);
	const FHyperTwistTrainingControlSettingsOwnershipInspectSurface ImportedRecallSurface =
		TrainingPanel->GetDisplayedControlSettingsOwnershipInspectSurface();
	TestTrue(
		TEXT("The control settings ownership surface must surface selector recall from the imported stored launch request when the active-deck cache is empty."),
		ImportedRecallSurface.bRepositoryBackedSelectorRecallReady
			&& ImportedRecallSurface.SelectorRecallLine.Contains(TEXT("runtime-imported-generated-mode"))
			&& ImportedRecallSurface.SelectorRecallLine.Contains(TEXT("phase6c/imported-generated-mode-surface"))
	);

	TrainingPanel->CachedLatestGeneratedModeLaunchRequestForActiveDeck =
		HyperTwistBrowserBridgeObjectTestInternal::MakeSampleGeneratedModeLaunchRequest();
	const FHyperTwistTrainingControlSettingsOwnershipInspectSurface RecalledSurface =
		TrainingPanel->GetDisplayedControlSettingsOwnershipInspectSurface();
	TestTrue(
		TEXT("The control settings ownership surface must surface repository-backed selector recall once a persisted launch request is present."),
		RecalledSurface.bRepositoryBackedSelectorRecallReady
	);
	TestEqual(
		TEXT("The control settings ownership surface must preserve the recalled selector count."),
		RecalledSurface.RecalledHigherDimensionalSelectorCount,
		4
	);
	TestTrue(
		TEXT("The control settings ownership surface must surface the generated-mode surface id in the selector recall line."),
		RecalledSurface.SelectorRecallLine.Contains(TEXT("phase6c/magic120cell/generated-mode-surface"))
	);
	TestFalse(
		TEXT("The control settings ownership surface must prefer the active-deck launch request over the imported fallback once both exist."),
		RecalledSurface.SelectorRecallLine.Contains(TEXT("phase6c/imported-generated-mode-surface"))
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoachDashboardControlSettingsOwnershipInspectSurfaceTest,
	"HyperTwist.Browser.CoachDashboard.ControlSettingsOwnershipInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoachDashboardControlSettingsOwnershipInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject<UHyperTwistCoachDashboardWidget>();
	TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard);
	if (CoachDashboard == nullptr)
	{
		return false;
	}

	CoachDashboard->RefreshCoachDashboardView();
	const FHyperTwistTrainingControlSettingsOwnershipInspectSurface Surface =
		CoachDashboard->GetDisplayedControlSettingsOwnershipInspectSurface();
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must stay structurally valid after a view refresh."),
		Surface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The coach dashboard control settings ownership surface must preserve the diagnostics headline."),
		Surface.Headline,
		TEXT("Control settings ownership")
	);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must retain the camera settings tool reference in its detail line."),
		Surface.DetailLine.Contains(TEXT("tool/camera-settings"))
	);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must retain the dedicated-family view profile references in its detail line."),
		Surface.DetailLine.Contains(TEXT("magic120cell-focus-view-profile"))
			&& Surface.DetailLine.Contains(TEXT("magiccube5d-projection-view-profile"))
	);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must retain dedicated family persistence and state-semantics ids in its detail line."),
		Surface.DetailLine.Contains(TEXT("magic120cell-persistence-boundary"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magic120cell/family-owned-scene-state"))
			&& Surface.DetailLine.Contains(TEXT("magiccube5d-persistence-boundary"))
			&& Surface.DetailLine.Contains(TEXT("phase6c/magiccube5d/family-owned-scene-state"))
	);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must keep the rendered enabled OpenXR project plugin truth explicit."),
		Surface.DetailLine.Contains(TEXT("project OpenXR plugin enabled"))
			&& Surface.DetailLine.Contains(TEXT("xr-openxr-training-preferences/v1"))
	);
	TestEqual(
		TEXT("The coach dashboard control settings ownership surface must preserve the structured XR host decision id."),
		Surface.XrHostDecisionId,
		TEXT("desktop-hosted-openxr-controller-widening-no-go")
	);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must preserve bounded camera and immersive continuity in structured form."),
		Surface.bCameraSettingsContinuityReady
			&& Surface.CameraSettingsExportArtifactId == TEXT("artifact/camera-export-json")
			&& Surface.bImmersiveSessionRecallReady
			&& Surface.ImmersiveSessionRecallBoundaryId
				== TEXT("immersive-training-session-recall-boundary")
	);
	TestEqual(
		TEXT("The coach dashboard control settings ownership surface must preserve the shipped Magic120Cell projection-tag count."),
		Surface.Magic120CellProjectionSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The coach dashboard control settings ownership surface must preserve the shipped Magic120Cell symmetry-preset count."),
		Surface.Magic120CellSymmetryPresetTagCount,
		5
	);
	TestEqual(
		TEXT("The coach dashboard control settings ownership surface must preserve the shipped MagicCube5D stereo-tag count."),
		Surface.MagicCube5DStereoSurfaceTagCount,
		5
	);
	TestEqual(
		TEXT("The coach dashboard control settings ownership surface must preserve the shipped MagicCube5D focus-surface count."),
		Surface.MagicCube5DFocusSurfaceTagCount,
		5
	);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must preserve the explicit enabled OpenXR project plugin posture."),
		Surface.bOpenXrProjectPluginEnabled
	);
		TestTrue(
			TEXT("The coach dashboard control settings ownership surface must expose the bounded XR preference, controller binding, and controller settings packet."),
			Surface.bXrPreferenceProfileReady
				&& Surface.bXrControllerBindingProfileReady
				&& Surface.bXrControllerSettingsOwnershipReady
				&& Surface.bXrControllerRebindingOwnershipReady
				&& Surface.XrRuntimeOwnerId == TEXT("xr/openxr-desktop-training-runtime-owner")
				&& Surface.XrPreferenceProfileId == TEXT("xr-openxr-training-preferences/v1")
				&& Surface.XrControllerBindingProfileId == TEXT("xr-openxr-motion-controllers/v1")
				&& Surface.XrControllerSettingsOwnerId
					== TEXT("xr-openxr-controller-settings-owner/v1")
				&& Surface.XrControllerRebindingSurfaceId
					== TEXT("xr-openxr-controller-rebinding-surface/v1")
				&& Surface.XrPreferenceFieldCount == 8
				&& Surface.XrControllerBindingAxisCount == 8
				&& Surface.XrSupportedControllerFamilyCount == 4
				&& Surface.XrControllerSettingsFieldCount == 8
				&& Surface.XrControllerRebindableInputCount == 12
				&& Surface.XrControllerLayoutPresetCount == 3
				&& !Surface.bFinishedControllerRebindingReady
				&& !Surface.bWindowsPackagedControllerProofReady
		);
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must preserve the structured No-Go decision and reopen requirements."),
		Surface.bNativeOpenXrControllerWideningNoGo
			&& Surface.bRequiresDedicatedRuntimeOwnersForReopen
			&& Surface.bRequiresUserFacingSettingsRebindingForReopen
			&& Surface.bRequiresWindowsPackagedControllerValidationForReopen
	);

	CoachDashboard->CachedLatestGeneratedModeLaunchRequestForActiveDeck =
		HyperTwistBrowserBridgeObjectTestInternal::MakeSampleGeneratedModeLaunchRequest();
	const FHyperTwistTrainingControlSettingsOwnershipInspectSurface RecalledSurface =
		CoachDashboard->GetDisplayedControlSettingsOwnershipInspectSurface();
	TestTrue(
		TEXT("The coach dashboard control settings ownership surface must reflect repository-backed selector recall from the latest persisted launch request."),
		RecalledSurface.bRepositoryBackedSelectorRecallReady
			&& RecalledSurface.SelectorRecallLine.Contains(TEXT("phase6c-higher-dimensional-launch-surface"))
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistTrainingPanelControlProfileRosterInspectSurfaceTest,
	"HyperTwist.Browser.TrainingPanel.ControlProfileRosterInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistTrainingPanelControlProfileRosterInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistTrainingPanelWidget* TrainingPanel = NewObject<UHyperTwistTrainingPanelWidget>();
	TestNotNull(TEXT("The training panel widget must be constructible."), TrainingPanel);
	if (TrainingPanel == nullptr)
	{
		return false;
	}

	const FHyperTwistTrainingControlProfileRosterInspectSurface Surface =
		TrainingPanel->GetDisplayedControlProfileRosterInspectSurface();
	TestTrue(
		TEXT("The control/profile roster surface must be structurally valid."),
		Surface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The control/profile roster surface must keep a stable headline."),
		Surface.Headline,
		TEXT("Selectable control and profile roster")
	);
	TestTrue(
		TEXT("The control/profile roster surface must report the current shipped classic keyboard profile."),
		Surface.bClassicKeyboardProfileReady
			&& Surface.ClassicKeyboardProfileName == TEXT("classic-wca-keyboard/v1")
			&& Surface.ClassicKeyboardBindingCount == 18
	);
	TestTrue(
		TEXT("The control/profile roster surface must spell out the shipped classic move roster."),
		Surface.ClassicKeyboardMoveRosterLine.Contains(TEXT("I/K = R/R'"))
			&& Surface.ClassicKeyboardMoveRosterLine.Contains(TEXT("J/F = U/U'"))
			&& Surface.ClassicKeyboardMoveRosterLine.Contains(TEXT("P/Q = z/z'"))
	);
	TestTrue(
		TEXT("The control/profile roster surface must report the immersive presence preset roster."),
		Surface.bImmersivePresenceProfileReady
			&& Surface.ImmersivePresenceContractId
				== TEXT("immersive-training-presence-control-contract")
			&& Surface.ImmersionIntensityPresetCount == 3
			&& Surface.ReducedDistractionPresetCount == 3
	);
	TestTrue(
		TEXT("The control/profile roster surface must report the shipped dedicated-family profile ids and selector counts."),
		Surface.bMagic120CellProfileReady
			&& Surface.bMagicCube5DProfileReady
			&& Surface.Magic120CellRuntimeProfileContractId
				== TEXT("magic120cell-runtime-profile")
			&& Surface.Magic120CellViewProfileContractId
				== TEXT("magic120cell-focus-view-profile")
			&& Surface.MagicCube5DRuntimeProfileContractId
				== TEXT("magiccube5d-runtime-profile")
			&& Surface.MagicCube5DViewProfileContractId
				== TEXT("magiccube5d-projection-view-profile")
			&& Surface.Magic120CellSelectorCount == 4
			&& Surface.MagicCube5DSelectorCount == 4
	);
	TestTrue(
		TEXT("The control/profile roster surface must now expose first-party controller rebinding ownership explicitly while keeping finished packaged proof false."),
		!Surface.bFinishedControllerRebindingReady
			&& Surface.bXrControllerSettingsOwnershipReady
			&& Surface.bXrControllerRebindingOwnershipReady
			&& !Surface.bWindowsPackagedControllerProofReady
	);
	TestTrue(
		TEXT("The control/profile roster surface must keep the current enabled OpenXR project plugin posture explicit."),
		Surface.bOpenXrProjectPluginEnabled
	);
		TestTrue(
			TEXT("The control/profile roster surface must expose the bounded XR controller profile and controller settings packet."),
			Surface.bXrPreferenceProfileReady
				&& Surface.bXrControllerBindingProfileReady
				&& Surface.bXrControllerSettingsOwnershipReady
				&& Surface.bXrControllerRebindingOwnershipReady
				&& Surface.XrRuntimeOwnerId == TEXT("xr/openxr-desktop-training-runtime-owner")
				&& Surface.XrPreferenceProfileId == TEXT("xr-openxr-training-preferences/v1")
				&& Surface.XrControllerBindingProfileId == TEXT("xr-openxr-motion-controllers/v1")
				&& Surface.XrControllerSettingsOwnerId
					== TEXT("xr-openxr-controller-settings-owner/v1")
				&& Surface.XrControllerRebindingSurfaceId
					== TEXT("xr-openxr-controller-rebinding-surface/v1")
				&& Surface.XrPreferenceFieldCount == 8
				&& Surface.XrControllerBindingAxisCount == 8
				&& Surface.XrSupportedControllerFamilyCount == 4
				&& Surface.XrControllerSettingsFieldCount == 8
				&& Surface.XrControllerRebindableInputCount == 12
				&& Surface.XrControllerLayoutPresetCount == 3
		);
	TestEqual(
		TEXT("The control/profile roster surface must expose a stable structured XR host decision id."),
		Surface.XrHostDecisionId,
		TEXT("desktop-hosted-openxr-controller-widening-no-go")
	);
	TestTrue(
		TEXT("The control/profile roster surface must keep the No-Go decision and reopen requirements explicit in structured form."),
		Surface.bNativeOpenXrControllerWideningNoGo
			&& Surface.bRequiresDedicatedRuntimeOwnersForReopen
			&& Surface.bRequiresUserFacingSettingsRebindingForReopen
			&& Surface.bRequiresWindowsPackagedControllerValidationForReopen
	);
		TestTrue(
			TEXT("The control/profile roster surface must say plainly that controller rebinding is first-party-owned while packaged proof is not yet shipped."),
			Surface.DetailLine.Contains(TEXT("not yet shipped"))
				&& Surface.DetailLine.Contains(TEXT("project OpenXR plugin is enabled"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-motion-controllers/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-settings-owner/v1"))
				&& Surface.DetailLine.Contains(TEXT("xr-openxr-controller-rebinding-surface/v1"))
		);
	TestTrue(
		TEXT("The control/profile roster surface must keep the fixed No-Go host decision visible alongside the unfinished controller rebinding truth."),
		Surface.DetailLine.Contains(TEXT("No-Go"))
	);
	TestFalse(
		TEXT("The control/profile roster surface must not fabricate repository-backed selector recall before a launch request has been observed."),
		Surface.bRepositoryBackedSelectorRecallReady
	);
	TestTrue(
		TEXT("The control/profile roster surface must explain when repository-backed selector recall is unavailable."),
		Surface.SelectorRecallLine.Contains(TEXT("unavailable"))
	);

	TrainingPanel->CachedImportedGeneratedModeLaunchRequest =
		HyperTwistBrowserBridgeObjectTestInternal::MakeSampleGeneratedModeLaunchRequest(
			TEXT("runtime-imported-generated-mode"),
			TEXT("phase6c/imported-generated-mode-surface")
		);
	const FHyperTwistTrainingControlProfileRosterInspectSurface ImportedRecallSurface =
		TrainingPanel->GetDisplayedControlProfileRosterInspectSurface();
	TestTrue(
		TEXT("The control/profile roster surface must surface selector recall from the imported stored launch request when the active-deck cache is empty."),
		ImportedRecallSurface.bRepositoryBackedSelectorRecallReady
			&& ImportedRecallSurface.SelectorRecallLine.Contains(TEXT("runtime-imported-generated-mode"))
			&& ImportedRecallSurface.SelectorRecallLine.Contains(TEXT("phase6c/imported-generated-mode-surface"))
	);

	TrainingPanel->CachedLatestGeneratedModeLaunchRequestForActiveDeck =
		HyperTwistBrowserBridgeObjectTestInternal::MakeSampleGeneratedModeLaunchRequest();
	const FHyperTwistTrainingControlProfileRosterInspectSurface RecalledSurface =
		TrainingPanel->GetDisplayedControlProfileRosterInspectSurface();
	TestTrue(
		TEXT("The control/profile roster surface must surface repository-backed selector recall once a persisted launch request is present."),
		RecalledSurface.bRepositoryBackedSelectorRecallReady
	);
	TestEqual(
		TEXT("The control/profile roster surface must preserve the recalled selector count."),
		RecalledSurface.RecalledHigherDimensionalSelectorCount,
		4
	);
	TestTrue(
		TEXT("The control/profile roster surface must keep the generated-mode surface id visible in the selector recall line."),
		RecalledSurface.SelectorRecallLine.Contains(TEXT("phase6c/magic120cell/generated-mode-surface"))
	);
	TestFalse(
		TEXT("The control/profile roster surface must prefer the active-deck launch request over the imported fallback once both exist."),
		RecalledSurface.SelectorRecallLine.Contains(TEXT("phase6c/imported-generated-mode-surface"))
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoachDashboardControlProfileRosterInspectSurfaceTest,
	"HyperTwist.Browser.CoachDashboard.ControlProfileRosterInspectSurface",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoachDashboardControlProfileRosterInspectSurfaceTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject<UHyperTwistCoachDashboardWidget>();
	TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard);
	if (CoachDashboard == nullptr)
	{
		return false;
	}

	CoachDashboard->RefreshCoachDashboardView();
	const FHyperTwistTrainingControlProfileRosterInspectSurface Surface =
		CoachDashboard->GetDisplayedControlProfileRosterInspectSurface();
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must stay structurally valid after a view refresh."),
		Surface.IsStructurallyValid()
	);
	TestEqual(
		TEXT("The coach dashboard control/profile roster surface must preserve the diagnostics headline."),
		Surface.Headline,
		TEXT("Selectable control and profile roster")
	);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must retain the shipped dedicated-family runtime/view profile references in its detail line."),
		Surface.DetailLine.Contains(TEXT("magic120cell-runtime-profile"))
			&& Surface.DetailLine.Contains(TEXT("magic120cell-focus-view-profile"))
			&& Surface.DetailLine.Contains(TEXT("magiccube5d-runtime-profile"))
			&& Surface.DetailLine.Contains(TEXT("magiccube5d-projection-view-profile"))
	);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must retain the classic keyboard profile fact in its detail line."),
		Surface.DetailLine.Contains(TEXT("classic-wca-keyboard/v1"))
	);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must retain the exact classic move roster in its detail line."),
		Surface.DetailLine.Contains(TEXT("I/K = R/R'"))
			&& Surface.DetailLine.Contains(TEXT("P/Q = z/z'"))
	);
	TestEqual(
		TEXT("The coach dashboard control/profile roster surface must preserve the structured XR host decision id."),
		Surface.XrHostDecisionId,
		TEXT("desktop-hosted-openxr-controller-widening-no-go")
	);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must preserve the explicit enabled OpenXR project plugin posture."),
		Surface.bOpenXrProjectPluginEnabled
	);
		TestTrue(
			TEXT("The coach dashboard control/profile roster surface must expose the bounded XR controller profile and controller settings packet."),
			Surface.bXrPreferenceProfileReady
				&& Surface.bXrControllerBindingProfileReady
				&& Surface.bXrControllerSettingsOwnershipReady
				&& Surface.bXrControllerRebindingOwnershipReady
				&& Surface.XrRuntimeOwnerId == TEXT("xr/openxr-desktop-training-runtime-owner")
				&& Surface.XrPreferenceProfileId == TEXT("xr-openxr-training-preferences/v1")
				&& Surface.XrControllerBindingProfileId == TEXT("xr-openxr-motion-controllers/v1")
				&& Surface.XrControllerSettingsOwnerId
					== TEXT("xr-openxr-controller-settings-owner/v1")
				&& Surface.XrControllerRebindingSurfaceId
					== TEXT("xr-openxr-controller-rebinding-surface/v1")
				&& Surface.XrPreferenceFieldCount == 8
				&& Surface.XrControllerBindingAxisCount == 8
				&& Surface.XrSupportedControllerFamilyCount == 4
				&& Surface.XrControllerSettingsFieldCount == 8
				&& Surface.XrControllerRebindableInputCount == 12
				&& Surface.XrControllerLayoutPresetCount == 3
				&& !Surface.bFinishedControllerRebindingReady
				&& !Surface.bWindowsPackagedControllerProofReady
		);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must preserve the structured No-Go decision and reopen requirements."),
		Surface.bNativeOpenXrControllerWideningNoGo
			&& Surface.bRequiresDedicatedRuntimeOwnersForReopen
			&& Surface.bRequiresUserFacingSettingsRebindingForReopen
			&& Surface.bRequiresWindowsPackagedControllerValidationForReopen
	);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must keep the rendered enabled OpenXR project plugin truth explicit."),
		Surface.DetailLine.Contains(TEXT("project OpenXR plugin is enabled"))
			&& Surface.DetailLine.Contains(TEXT("xr-openxr-motion-controllers/v1"))
	);
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must keep the fixed No-Go host decision visible in its rendered detail line."),
		Surface.DetailLine.Contains(TEXT("No-Go"))
	);

	CoachDashboard->CachedLatestGeneratedModeLaunchRequestForActiveDeck =
		HyperTwistBrowserBridgeObjectTestInternal::MakeSampleGeneratedModeLaunchRequest();
	const FHyperTwistTrainingControlProfileRosterInspectSurface RecalledSurface =
		CoachDashboard->GetDisplayedControlProfileRosterInspectSurface();
	TestTrue(
		TEXT("The coach dashboard control/profile roster surface must reflect repository-backed selector recall from the latest persisted launch request."),
		RecalledSurface.bRepositoryBackedSelectorRecallReady
			&& RecalledSurface.SelectorRecallLine.Contains(TEXT("phase6c-higher-dimensional-launch-surface"))
	);
	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistCoachDashboardControlSurfaceStructuredTextArtifactsTest,
	"HyperTwist.Browser.CoachDashboard.ControlSurfaceStructuredTextArtifacts",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistCoachDashboardControlSurfaceStructuredTextArtifactsTest::RunTest(
	const FString& Parameters
)
{
	UHyperTwistCoachDashboardWidget* CoachDashboard = NewObject<UHyperTwistCoachDashboardWidget>();
	TestNotNull(TEXT("The coach dashboard widget must be constructible."), CoachDashboard);
	if (CoachDashboard == nullptr)
	{
		return false;
	}

	CoachDashboard->TakeWidget();
	CoachDashboard->RefreshCoachDashboardView();

	const FHyperTwistTrainingControlInputReadinessInspectSurface ControlInputSurface =
		CoachDashboard->GetDisplayedControlInputReadinessInspectSurface();
	const FHyperTwistTrainingControlSettingsOwnershipInspectSurface ControlSettingsSurface =
		CoachDashboard->GetDisplayedControlSettingsOwnershipInspectSurface();
	const FHyperTwistTrainingControlProfileRosterInspectSurface ControlProfileSurface =
		CoachDashboard->GetDisplayedControlProfileRosterInspectSurface();

	UTextBlock* ControlInputSummaryTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessDetail")
		);
	UTextBlock* ControlInputClassicCubeTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessClassicCube")
		);
	UTextBlock* ControlInputClassicPointersTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessClassicPointers")
		);
	UTextBlock* ControlInputActionShortcutsTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessActionShortcuts")
		);
	UTextBlock* ControlInputXrTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessXr")
		);
	UTextBlock* ControlInputHigherDimensionalTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessHigherDimensional")
		);
	UTextBlock* ControlInputPreferencesTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessPreferences")
		);
	UTextBlock* ControlInputNextPacketTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlInputReadinessNextPacket")
		);
	TestNotNull(
		TEXT("The coach dashboard must build the control/input summary text row."),
		ControlInputSummaryTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured classic-cube control/input row."),
		ControlInputClassicCubeTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured classic-pointer control/input row."),
		ControlInputClassicPointersTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured action-shortcut control/input row."),
		ControlInputActionShortcutsTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured XR control/input row."),
		ControlInputXrTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured higher-dimensional control/input row."),
		ControlInputHigherDimensionalTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured preferences continuity row."),
		ControlInputPreferencesTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured next-packet control/input row."),
		ControlInputNextPacketTextBlock
	);
	if (ControlInputSummaryTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The control/input summary row must render the surface summary instead of the collapsed detail line."),
			ControlInputSummaryTextBlock->GetText().ToString(),
			ControlInputSurface.SummaryLine
		);
	}
	if (ControlInputClassicCubeTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured classic-cube control/input row must mirror the inspect surface."),
			ControlInputClassicCubeTextBlock->GetText().ToString(),
			ControlInputSurface.ClassicCubeStatusLine
		);
	}
	if (ControlInputClassicPointersTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured classic-pointer control/input row must mirror the inspect surface."),
			ControlInputClassicPointersTextBlock->GetText().ToString(),
			ControlInputSurface.ClassicCubePointerLine
		);
	}
	if (ControlInputActionShortcutsTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured action-shortcut control/input row must mirror the inspect surface."),
			ControlInputActionShortcutsTextBlock->GetText().ToString(),
			ControlInputSurface.ClassicCubeActionShortcutLine
		);
	}
	if (ControlInputXrTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured XR control/input row must mirror the inspect surface."),
			ControlInputXrTextBlock->GetText().ToString(),
			ControlInputSurface.XrStatusLine
		);
	}
	if (ControlInputHigherDimensionalTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured higher-dimensional control/input row must mirror the inspect surface."),
			ControlInputHigherDimensionalTextBlock->GetText().ToString(),
			ControlInputSurface.HigherDimensionalStatusLine
		);
		TestTrue(
			TEXT("The structured higher-dimensional control/input row must expose the concrete dedicated-family runtime ownership ids."),
			ControlInputHigherDimensionalTextBlock->GetText().ToString().Contains(
				TEXT("phase6c/magic120cell/runtime-host-surface"))
				&& ControlInputHigherDimensionalTextBlock->GetText().ToString().Contains(
					TEXT("phase6c/magiccube5d/interactive-scene-surface"))
		);
	}
	if (ControlInputPreferencesTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured preferences continuity row must mirror the inspect surface."),
			ControlInputPreferencesTextBlock->GetText().ToString(),
			ControlInputSurface.PreferencesStatusLine
		);
		TestTrue(
			TEXT("The structured preferences continuity row must expose the shipped camera-export and immersive session-recall ids."),
			ControlInputPreferencesTextBlock->GetText().ToString().Contains(
				TEXT("artifact/camera-export-json"))
				&& ControlInputPreferencesTextBlock->GetText().ToString().Contains(
					TEXT("immersive-training-session-recall-boundary"))
		);
	}
	if (ControlInputNextPacketTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured next-packet control/input row must mirror the inspect surface."),
			ControlInputNextPacketTextBlock->GetText().ToString(),
			ControlInputSurface.NextPacketLine
		);
	}

	UTextBlock* ControlSettingsSummaryTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipDetail")
		);
	UTextBlock* ControlSettingsCameraTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipCamera")
		);
	UTextBlock* ControlSettingsImmersiveTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipImmersive")
		);
	UTextBlock* ControlSettingsMagic120CellTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipMagic120Cell")
		);
	UTextBlock* ControlSettingsMagicCube5DTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipMagicCube5D")
		);
	UTextBlock* ControlSettingsSelectorsTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipSelectors")
		);
	UTextBlock* ControlSettingsSelectorRecallTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipSelectorRecall")
		);
	UTextBlock* ControlSettingsXrTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlSettingsOwnershipXrGap")
		);
	TestNotNull(
		TEXT("The coach dashboard must build the control-settings summary text row."),
		ControlSettingsSummaryTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured camera-settings row."),
		ControlSettingsCameraTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured immersive-settings row."),
		ControlSettingsImmersiveTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured Magic120Cell settings row."),
		ControlSettingsMagic120CellTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured MagicCube5D settings row."),
		ControlSettingsMagicCube5DTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured selector-settings row."),
		ControlSettingsSelectorsTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured selector-recall row."),
		ControlSettingsSelectorRecallTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured XR settings-boundary row."),
		ControlSettingsXrTextBlock
	);
	if (ControlSettingsSummaryTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The control-settings summary row must render the surface summary instead of the collapsed detail line."),
			ControlSettingsSummaryTextBlock->GetText().ToString(),
			ControlSettingsSurface.SummaryLine
		);
	}
	if (ControlSettingsCameraTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured camera-settings row must mirror the inspect surface."),
			ControlSettingsCameraTextBlock->GetText().ToString(),
			ControlSettingsSurface.CameraSettingsLine
		);
	}
	if (ControlSettingsImmersiveTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured immersive-settings row must mirror the inspect surface."),
			ControlSettingsImmersiveTextBlock->GetText().ToString(),
			ControlSettingsSurface.ImmersiveSettingsLine
		);
	}
	if (ControlSettingsMagic120CellTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured Magic120Cell settings row must mirror the inspect surface."),
			ControlSettingsMagic120CellTextBlock->GetText().ToString(),
			ControlSettingsSurface.Magic120CellSettingsLine
		);
		TestTrue(
			TEXT("The structured Magic120Cell settings row must expose the shipped projection, symmetry, visibility, and focus counts."),
			ControlSettingsMagic120CellTextBlock->GetText().ToString().Contains(TEXT("projection tags 5"))
				&& ControlSettingsMagic120CellTextBlock->GetText().ToString().Contains(TEXT("symmetry presets 5"))
				&& ControlSettingsMagic120CellTextBlock->GetText().ToString().Contains(TEXT("visibility presets 5"))
				&& ControlSettingsMagic120CellTextBlock->GetText().ToString().Contains(TEXT("focus surfaces 5"))
		);
	}
	if (ControlSettingsMagicCube5DTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured MagicCube5D settings row must mirror the inspect surface."),
			ControlSettingsMagicCube5DTextBlock->GetText().ToString(),
			ControlSettingsSurface.MagicCube5DSettingsLine
		);
		TestTrue(
			TEXT("The structured MagicCube5D settings row must expose the shipped projection, stereo, visibility, and focus counts."),
			ControlSettingsMagicCube5DTextBlock->GetText().ToString().Contains(TEXT("projection tags 5"))
				&& ControlSettingsMagicCube5DTextBlock->GetText().ToString().Contains(TEXT("stereo tags 5"))
				&& ControlSettingsMagicCube5DTextBlock->GetText().ToString().Contains(TEXT("visibility tags 5"))
				&& ControlSettingsMagicCube5DTextBlock->GetText().ToString().Contains(TEXT("focus surfaces 5"))
		);
	}
	if (ControlSettingsSelectorsTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured selector-settings row must mirror the inspect surface."),
			ControlSettingsSelectorsTextBlock->GetText().ToString(),
			ControlSettingsSurface.SelectorSettingsLine
		);
	}
	if (ControlSettingsSelectorRecallTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured selector-recall row must mirror the inspect surface."),
			ControlSettingsSelectorRecallTextBlock->GetText().ToString(),
			ControlSettingsSurface.SelectorRecallLine
		);
	}
	if (ControlSettingsXrTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured XR settings-boundary row must mirror the inspect surface."),
			ControlSettingsXrTextBlock->GetText().ToString(),
			ControlSettingsSurface.XrGapLine
		);
	}

	UTextBlock* ControlProfileSummaryTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlProfileRosterDetail")
		);
	UTextBlock* ControlProfileKeyboardTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlProfileRosterClassicKeyboard")
		);
	UTextBlock* ControlProfileMoveRosterTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlProfileRosterMoveRoster")
		);
	UTextBlock* ControlProfilePreferencesGapTextBlock =
		HyperTwistBrowserBridgeObjectTestInternal::FindDashboardTextBlock(
			CoachDashboard,
			TEXT("CoachControlProfileRosterPreferencesGap")
		);
	TestNotNull(
		TEXT("The coach dashboard must build the control-profile summary text row."),
		ControlProfileSummaryTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured classic-keyboard roster row."),
		ControlProfileKeyboardTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured classic move-roster row."),
		ControlProfileMoveRosterTextBlock
	);
	TestNotNull(
		TEXT("The coach dashboard must build the structured preferences-gap roster row."),
		ControlProfilePreferencesGapTextBlock
	);
	if (ControlProfileSummaryTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The control-profile summary row must render the surface summary instead of the collapsed detail line."),
			ControlProfileSummaryTextBlock->GetText().ToString(),
			ControlProfileSurface.SummaryLine
		);
	}
	if (ControlProfileKeyboardTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured classic-keyboard roster row must mirror the inspect surface."),
			ControlProfileKeyboardTextBlock->GetText().ToString(),
			ControlProfileSurface.ClassicKeyboardProfileLine
		);
	}
	if (ControlProfileMoveRosterTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured classic move-roster row must mirror the inspect surface."),
			ControlProfileMoveRosterTextBlock->GetText().ToString(),
			ControlProfileSurface.ClassicKeyboardMoveRosterLine
		);
	}
	if (ControlProfilePreferencesGapTextBlock != nullptr)
	{
		TestEqual(
			TEXT("The structured preferences-gap roster row must mirror the inspect surface."),
			ControlProfilePreferencesGapTextBlock->GetText().ToString(),
			ControlProfileSurface.PreferencesGapLine
		);
	}

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetAuthoritativeShellArtifactsTest,
	"HyperTwist.Browser.Widget.AuthoritativeShellArtifacts",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetAuthoritativeShellArtifactsTest::RunTest(const FString& Parameters)
{
	const FString ShellSourcePath = UHyperTwistBrowserWidget::ResolveBundledBrowserShellSourcePath();
	const FString BootstrapScriptPath = FPaths::Combine(
		FPaths::ProjectDir(),
		TEXT(".."),
		TEXT("Content"),
		TEXT("Browser"),
		TEXT("src"),
		TEXT("browser-runtime-bootstrap.js")
	);
	const FString FallbackRuntimePath = FPaths::Combine(
		FPaths::ProjectDir(),
		TEXT(".."),
		TEXT("Content"),
		TEXT("Browser"),
		TEXT("src"),
		TEXT("browser-spatial-runtime-fallback.js")
	);

	TestTrue(TEXT("The authoritative browser shell source file must exist."), FPaths::FileExists(ShellSourcePath));
	TestTrue(TEXT("The browser bootstrap script must exist."), FPaths::FileExists(BootstrapScriptPath));
	TestTrue(TEXT("The clean-checkout fallback runtime must exist."), FPaths::FileExists(FallbackRuntimePath));

	FString ShellSourceHtml;
	TestTrue(
		TEXT("The authoritative browser shell HTML must be readable."),
		FFileHelper::LoadFileToString(ShellSourceHtml, *ShellSourcePath)
	);
	TestTrue(
		TEXT("The authoritative browser shell must bootstrap through the plain-JS loader."),
		ShellSourceHtml.Contains(TEXT("browser-runtime-bootstrap.js"))
	);
	TestFalse(
		TEXT("The authoritative browser shell must not point directly at a TypeScript source entrypoint."),
		ShellSourceHtml.Contains(TEXT("browser-spatial-runtime.ts"))
	);

	return true;
}

IMPLEMENT_SIMPLE_AUTOMATION_TEST(
	FHyperTwistBrowserWidgetStatusSurfaceArtifactsTest,
	"HyperTwist.Browser.Widget.StatusSurfaceArtifacts",
	EAutomationTestFlags::EditorContext | EAutomationTestFlags::EngineFilter
)

bool FHyperTwistBrowserWidgetStatusSurfaceArtifactsTest::RunTest(const FString& Parameters)
{
	const FString BundledShellStatusSourcePath = FPaths::Combine(
		FPaths::ProjectDir(),
		TEXT(".."),
		TEXT("Content"),
		TEXT("Browser"),
		TEXT("src"),
		TEXT("runtime"),
		TEXT("shell.ts")
	);
	const FString FallbackRuntimePath = FPaths::Combine(
		FPaths::ProjectDir(),
		TEXT(".."),
		TEXT("Content"),
		TEXT("Browser"),
		TEXT("src"),
		TEXT("browser-spatial-runtime-fallback.js")
	);

	TestTrue(
		TEXT("The bundled runtime shell source must exist for runtime status verification."),
		FPaths::FileExists(BundledShellStatusSourcePath)
	);
	TestTrue(
		TEXT("The fallback runtime source must exist for runtime status verification."),
		FPaths::FileExists(FallbackRuntimePath)
	);

	FString BundledShellSource;
	TestTrue(
		TEXT("The bundled runtime shell source must be readable."),
		FFileHelper::LoadFileToString(BundledShellSource, *BundledShellStatusSourcePath)
	);
	TestTrue(
		TEXT("The bundled runtime shell must expose the Browser Runtime Status surface."),
		BundledShellSource.Contains(TEXT("Browser Runtime Status"))
	);
	TestTrue(
		TEXT("The bundled runtime shell must surface the retained queued command count at runtime-ready."),
		BundledShellSource.Contains(TEXT("queuedCommandCountAtRuntimeReady"))
	);
	TestTrue(
		TEXT("The bundled runtime shell must surface the last shell-state receipt timestamp."),
		BundledShellSource.Contains(TEXT("lastShellStateReceivedAtUtc"))
	);

	FString FallbackRuntimeSource;
	TestTrue(
		TEXT("The fallback runtime source must be readable."),
		FFileHelper::LoadFileToString(FallbackRuntimeSource, *FallbackRuntimePath)
	);
	TestTrue(
		TEXT("The fallback runtime must also expose the Browser Runtime Status surface."),
		FallbackRuntimeSource.Contains(TEXT("Browser Runtime Status"))
	);
	TestTrue(
		TEXT("The fallback runtime must surface the retained queued shell-state count at runtime-ready."),
		FallbackRuntimeSource.Contains(TEXT("queuedShellStateCountAtRuntimeReady"))
	);
	TestTrue(
		TEXT("The fallback runtime must surface the last command receipt timestamp."),
		FallbackRuntimeSource.Contains(TEXT("lastCommandReceivedAtUtc"))
	);

	return true;
}

#endif
