void AFunctionalTest::FinishTest(TEnumAsByte<EFunctionalTestResult::Type> TestResult, const FString& Message)
{
	const static UEnum* FTestResultTypeEnum = FindObject<UEnum>( NULL, TEXT("FunctionalTesting.FunctionalTest.EFunctionalTestResult") );
	
	bIsRunning = false;
	SetActorTickEnabled(false);

	OnTestFinished.Broadcast();

	AActor** ActorToDestroy = AutoDestroyActors.GetTypedData();

	for (int32 ActorIndex = 0; ActorIndex < AutoDestroyActors.Num(); ++ActorIndex, ++ActorToDestroy)
	{
		if (*ActorToDestroy != NULL)
		{
			// will be removed next frame
			(*ActorToDestroy)->SetLifeSpan( 0.01f );
		}
	}

	const FText ResultText = FTestResultTypeEnum->GetEnumText( TestResult.GetValue() );
	const FString OutMessage = FString::Printf(TEXT("%s> Result: %s> %s")
		, *GetActorLabel()
		, *ResultText.ToString()
		, Message.IsEmpty() == false ? *Message : TEXT("Test finished") );

	AutoDestroyActors.Reset();

	EMessageSeverity::Type MessageLogSeverity = EMessageSeverity::Info;
	
	switch (TestResult.GetValue())
	{
		case EFunctionalTestResult::Invalid:
		case EFunctionalTestResult::Error:
			UE_VLOG(this, LogFunctionalTest, Error, TEXT("%s"), *OutMessage);
			MessageLogSeverity = EMessageSeverity::Error;
			break;
		case EFunctionalTestResult::Running:
			UE_VLOG(this, LogFunctionalTest, Warning, TEXT("%s"), *OutMessage);
			MessageLogSeverity = EMessageSeverity::Warning;
			break;
		case EFunctionalTestResult::Failed:
			UE_VLOG(this, LogFunctionalTest, Error, TEXT("%s"), *OutMessage);
			MessageLogSeverity = EMessageSeverity::Error;
			break;
		default:
			UE_VLOG(this, LogFunctionalTest, Log, TEXT("%s"), *OutMessage);
			break;
	}

	FMessageLog("FunctionalTestingLog").Message(MessageLogSeverity, FText::FromString(GetActorLabel()))
		->AddToken( FTextToken::Create( ResultText ) )
		->AddToken( FTextToken::Create( Message.IsEmpty() == false ? FText::FromString(Message) : NSLOCTEXT("FunctionalTest", "FinishedTest", "Test finished") ) );

	TestFinishedObserver.ExecuteIfBound(this);
}
void UJavascriptWidget::OnListenForInputAction(FName ActionName, TEnumAsByte< EInputEvent > EventType, bool bConsume)
{
	if (!InputComponent)
	{
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION < 12
		if (APlayerController* Controller = GetOwningPlayer())
		{
			InputComponent = NewObject< UInputComponent >(this, NAME_None, RF_Transient);
			InputComponent->bBlockInput = bStopAction;
			InputComponent->Priority = Priority;
			Controller->PushInputComponent(InputComponent);
		}		
#else
		InitializeInputComponent();
#endif
	}

	if (InputComponent)
	{
		FInputActionBinding NewBinding(ActionName, EventType.GetValue());
		NewBinding.bConsumeInput = bConsume;
		NewBinding.ActionDelegate.GetDelegateForManualSet().BindUObject(this, &ThisClass::OnInputActionByName, ActionName);
		InputComponent->AddActionBinding(NewBinding);
	}
}
void AFunctionalTest::FinishTest(TEnumAsByte<EFunctionalTestResult::Type> TestResult, const FString& Message)
{
	const static UEnum* FTestResultTypeEnum = FindObject<UEnum>( NULL, TEXT("FunctionalTesting.FunctionalTest.EFunctionalTestResult") );
	
	if (bIsRunning == false)
	{
		// ignore
		return;
	}

	Result = TestResult;

	bIsRunning = false;
	SetActorTickEnabled(false);

	OnTestFinished.Broadcast();

	AActor** ActorToDestroy = AutoDestroyActors.GetData();

	for (int32 ActorIndex = 0; ActorIndex < AutoDestroyActors.Num(); ++ActorIndex, ++ActorToDestroy)
	{
		if (*ActorToDestroy != NULL)
		{
			// will be removed next frame
			(*ActorToDestroy)->SetLifeSpan( 0.01f );
		}
	}

	const FText ResultText = FTestResultTypeEnum->GetEnumText( TestResult.GetValue() );
	const FString OutMessage = FString::Printf(TEXT("%s %s: \"%s\'")
		, *GetActorLabel()
		, *ResultText.ToString()
		, Message.IsEmpty() == false ? *Message : TEXT("Test finished") );
	const FString AdditionalDetails = GetAdditionalTestFinishedMessage(TestResult) + FString::Printf(TEXT(", time %.2fs"), TotalTime);

	AutoDestroyActors.Reset();
		
	switch (TestResult.GetValue())
	{
		case EFunctionalTestResult::Invalid:
		case EFunctionalTestResult::Error:
		case EFunctionalTestResult::Failed:
			UE_VLOG(this, LogFunctionalTest, Error, TEXT("%s"), *OutMessage);
			UFunctionalTestingManager::AddError(FText::FromString(OutMessage));
			break;

		case EFunctionalTestResult::Running:
			UE_VLOG(this, LogFunctionalTest, Warning, TEXT("%s"), *OutMessage);
			UFunctionalTestingManager::AddWarning(FText::FromString(OutMessage));
			break;
		
		default:
			UE_VLOG(this, LogFunctionalTest, Log, TEXT("%s"), *OutMessage);
			UFunctionalTestingManager::AddLogItem(FText::FromString(OutMessage));
			break;
	}
	
	if (AdditionalDetails.IsEmpty() == false)
	{
		UFunctionalTestingManager::AddLogItem(FText::FromString(AdditionalDetails));
	}

	TestFinishedObserver.ExecuteIfBound(this);
}