Spawning a window and widget in SIMPLE_AUTOMATION_TEST

Hello,
I’m wondering if I can pick your brains a bit …

Context:

  • I’m working on some automated testing, ultimate goal is to run the game/app (as if you pressed play in editor or ran .exe) and pipe some input into it, then take some screenshots.

Progress:

  • Used a tutorial and got as far as IMPLEMENT_SIMPLE_AUTOMATION_TEST and RunTest getting called.
  • I’m pretty sure FDriverSequenceRef will let me add button sequences and FScreenshotRequest will let me make screenshots … but that’s further then I am now.
  • I got as far as creating a new window and spawning a widget I’m trying to test.

Problem 1: new window shows up but it is blank/black, regardless of widget being loaded or not.

  • Even GEngine->AddOnScreenDebugMessage does not show up … telling me something very core is missing.
    – I’m wondering if you can think of what that might be?
    – My current guess is that .AddWindow(…) accepts a [ ] content … which is empty for me.
    — can also be done with Window->SetContent( );
    — this does not explain why GEngine->AddOnScreenDebugMessage would not work and I’m trying to fix that first.

Problem 2: likely quite specific to our widget, but when our widget tries to run it fails on GameInstance->GetSubsystem internally in the engine well inside GameInstance::SubsystemCollection.h::SubsystemMap

  • but this could also mean something early/core is missing like a general subsystem handler or the like …

Init code used (with some fluff edited)

IAutomationDriverModule::Get().Enable();
Window = FSlateApplication::Get().AddWindow( SNew(SWindow) ... .ClientSize(FVector2D(1920, 1080) ... /*[]*/ )
Window->ShowWindow();
Window->BringToFront(true);
FSlateApplication::Get().SetKeyboardFocus(Window ..)

Driver = IAutomationDriverModule::Get().CreateDriver();
EKeys::Initialize();
UGameInstance* GameInstance = NewObject<UGameInstance>(GEngine);
GameInstance->InitializeStandalone(); // creates WorldContext, UWorld?

const auto& WorldContext = GEngine->GetWorldContexts()[0];
auto Camera = WorldContext.World()->SpawnActor<ACameraActor>();
Camera->GetCameraComponent()->Activate(); // likely needed for visuals 
PlayerController = UGameplayStatics::GetPlayerController(WorldContext.World(), 0); // maybe needed for input?

GEngine->AddOnScreenDebugMessage(-1, 15.0f, FColor::Yellow, TEXT("HERE 1 2 3")); // does now show up

Update: got the stuff loading via AutomationOpenMap skipping all the window creation and anything to do with slate.

Unfortunately I now hit automation driver locking up the editor like here:

I ended up not using automation driver at all … just couldn’t figure out why it locked up in execute sequence.

Ended up using this:

DEFINE_LATENT_AUTOMATION_COMMAND_ONE_PARAMETER(TExecuteSequenceTypeButton, TArray<FKey>, Keys);
bool TExecuteSequenceTypeButton::Update()
{
	//
	// Input through Slate
	//
	FSlateApplication::Get().SetUserFocusToGameViewport(0);
	for (int i = 0; i < Keys.Num(); i++)
	{
		const FKey Key = Keys[i];
		uint32 KeyCode, CharCode;
		{
			const uint32* KeyCodePtr;
			const uint32* CharCodePtr;
			FInputKeyManager::Get().GetCodesFromKey(Key, KeyCodePtr, CharCodePtr);

			KeyCode = KeyCodePtr ? *KeyCodePtr : 0;
			CharCode = CharCodePtr ? *CharCodePtr : 0;
		}

		FModifierKeysState ModifierKeys(false, false, false, false, false, false, false, false, false);
		FKeyEvent KeyEvent(Key, ModifierKeys, 0, false, KeyCode, CharCode);

		FSlateApplication::Get().ProcessKeyDownEvent(KeyEvent);
		FSlateApplication::Get().ProcessKeyUpEvent(KeyEvent);
	}
	return true;
}