class: LocatorAssertions

Specter provides custom expect matchers specifically designed for Unreal Engine. These assertions will automatically poll the engine (retrying until a timeout) until the condition is met, exactly like web Playwright.

Gameplay Ability System (GAS)

Assertions for polling and verifying Gameplay Tags, Attributes, Abilities, and Effects.

expect(actor).toHaveGameplayTag

Ensures the given actor currently possesses the specified Gameplay Tag on its Ability System Component.
await expect(enemy).toHaveGameplayTag("Status.Stunned");

Arguments

NameTypeDescription
tag stringThe Gameplay Tag string (e.g., 'Status.Stunned').
Returns:Promise<void>

expect(actor).toHaveAnyGameplayTags

Ensures the given actor has at least one of the specified Gameplay Tags.
await expect(enemy).toHaveAnyGameplayTags(["Status.Stunned", "Status.Rooted"]);

Arguments

NameTypeDescription
tags string[]An array of Gameplay Tags.
Returns:Promise<void>

expect(actor).toHaveAllGameplayTags

Ensures the given actor has all of the specified Gameplay Tags.
await expect(enemy).toHaveAllGameplayTags(["Status.Stunned", "Status.Burning"]);

Arguments

NameTypeDescription
tags string[]An array of Gameplay Tags.
Returns:Promise<void>

expect(actor).toHaveGameplayTagCount

Verifies the exact count of a specific Gameplay Tag.
await expect(enemy).toHaveGameplayTagCount("Status.Poisoned", 3);

Arguments

NameTypeDescription
tag stringThe Gameplay Tag.
expectedCount numberThe expected exact count.
Returns:Promise<void>

expect(actor).toHaveAttributeValue

Polls the actor's Ability System attributes and passes once the specified attribute exactly matches the expected value.
await expect(defender).toHaveAttributeValue("MMAttributeSet", "Health", 10);

Arguments

NameTypeDescription
set stringThe Attribute Set class name.
attribute stringThe specific attribute name.
expectedValue numberThe exact numeric value to wait for.
Returns:Promise<void>

expect(actor).toHaveAttributeBaseValue

Polls the actor's Ability System attributes and passes once the specified base attribute exactly matches the expected value.
await expect(defender).toHaveAttributeBaseValue("MMAttributeSet", "MaxHealth", 100);

Arguments

NameTypeDescription
set stringThe Attribute Set class name.
attribute stringThe specific base attribute name.
expectedValue numberThe exact numeric value to wait for.
Returns:Promise<void>

expect(actor).toHaveAttributeChange

Polls the actor's Ability System attributes and passes if the specified attribute changes by the expected delta within the timeout.
await expect(defender).toHaveAttributeChange("MMAttributeSet", "Health", {
  delta: -attackerDamage,
  instigator: attacker,
  ability: "Default__GA_Marshmallow_Punch_C"
}, async () => {
  await attacker.triggerAbilityByTag("Ability.Attack.Melee");
});

Arguments

NameTypeDescription
set stringThe Attribute Set class name.
attribute stringThe specific attribute name.
options ObjectOptions including { delta?: number, instigator?: ActorLocator, ability?: string }.
action optionalFunctionAn async callback that triggers the attribute change.
Returns:Promise<void>

expect(actor).toHaveGameplayEffect

Verifies the actor has an active Gameplay Effect of the given class.
await expect(hero).toHaveGameplayEffect("/Game/Effects/GE_Shield");

Arguments

NameTypeDescription
effectClassPath stringThe effect class path.
Returns:Promise<void>

expect(actor).toHaveGameplayEffectStackCount

Verifies the actor has an active Gameplay Effect with a specific stack count.
await expect(hero).toHaveGameplayEffectStackCount("/Game/Effects/GE_Bleed", 5);

Arguments

NameTypeDescription
effectClassPath stringThe effect class path.
expectedCount numberThe expected stack count.
Returns:Promise<void>

expect(actor).toHaveGameplayEffectLevel

Verifies the actor has an active Gameplay Effect with a specific level.
await expect(hero).toHaveGameplayEffectLevel("/Game/Effects/GE_Buff", 2);

Arguments

NameTypeDescription
effectClassPath stringThe effect class path.
expectedLevel numberThe expected level.
Returns:Promise<void>

expect(actor).toHaveGameplayAbility

Verifies the actor has been granted a specific Gameplay Ability.
await expect(hero).toHaveGameplayAbility("/Game/Abilities/GA_Dash");

Arguments

NameTypeDescription
abilityClassPath stringThe ability class path.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toBeExecutingAbility

Verifies the actor is currently actively executing a specific Gameplay Ability.
await expect(hero).toBeExecutingAbility("/Game/Abilities/GA_Ultimate");

Arguments

NameTypeDescription
abilityClassPath stringThe ability class path.
Returns:Promise<void>

expect(actor).toHaveAbilityCooldown

Polls the cooldown of a specific ability until it meets the configured operator condition.
await expect(hero).toHaveAbilityCooldown("/Game/Abilities/GA_Dash", { operator: "<=", expectedValue: 0 });

Arguments

NameTypeDescription
abilityClassPath stringThe ability class path.
options optionalObjectConfiguration object: { operator?: string, expectedValue?: number, timeout?: number }.
Returns:Promise<void>

Movement & Spatial

Assertions for positioning, physics, and character movement tests.

expect(actor).toBeFalling

Verifies the actor's movement component is currently in a falling state.
await expect(enemy).toBeFalling();
Returns:Promise<void>

expect(actor).toBeCrouching

Verifies the actor's movement component is currently in a crouching state.
await expect(player).toBeCrouching();
Returns:Promise<void>

expect(actor).toBeFlying

Verifies the actor's movement component is currently in a flying state.
await expect(drone).toBeFlying();
Returns:Promise<void>

expect(actor).toHaveVelocity

Verifies the actor's current velocity is greater than or equal to the expected speed (in cm/s).
// Pass if speed >= 600 cm/s
await expect(playerActor).toHaveVelocity(600);

Arguments

NameTypeDescription
expectedSpeed numberThe minimum expected speed threshold.
Returns:Promise<void>

expect(actor).toBeWithinDistanceOf

Verifies the actor is within a specific distance of another actor.
await expect(enemy).toBeWithinDistanceOf(world.actor('Player'), 200);

Arguments

NameTypeDescription
otherActorLocator ActorLocatorThe locator of the target actor.
maxDistance numberThe maximum distance allowed (in cm).
Returns:Promise<void>

expect(actor).toBeFacing

Verifies the actor is currently facing towards another actor's location.
await expect(turret).toBeFacing(world.actor('Player'));

Arguments

NameTypeDescription
otherActorLocator ActorLocatorThe locator of the target actor.
Returns:Promise<void>

expect(actor).toHaveMovedFurtherThan

A powerful spatial assertion that ensures the actor's 3D location has changed by at least the specified distance from a starting point.
const startPos = await enemy.getLocation();
await world.console('cheat knockback');

await expect(enemy).toHaveMovedFurtherThan(startPos, 500);

Arguments

NameTypeDescription
startPos Vector3The starting 3D coordinate.
distance numberThe minimum distance in Unreal Units (cm) the actor must have moved.
Returns:Promise<void>

expect(actor).toHaveLocation

Polls the actor's 3D position until it is within the specified tolerance radius of the expected location.
await expect(enemy).toHaveLocation({ x: 100, y: 200, z: 0 }, 10.0);

Arguments

NameTypeDescription
expectedLocation Vector3The expected {x, y, z} world coordinate.
tolerance optionalnumberThe maximum acceptable distance from the target in cm (Default: 5.0).
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

Animation & Montages

Assertions for testing attack hitboxes or ability timings.

expect(skeleton).toBePlayingMontage

Verifies the skeletal mesh is actively playing the specified animation montage.
await expect(heroSkeleton).toBePlayingMontage("/Game/Animations/AM_Attack");

Arguments

NameTypeDescription
montageClassPath stringThe montage class path.
Returns:Promise<void>

expect(skeleton).toHaveMontageSection

Verifies the skeletal mesh is currently in the specified section of their active montage.
await expect(bossSkeleton).toHaveMontageSection("Phase2");

Arguments

NameTypeDescription
sectionName stringThe name of the montage section.
Returns:Promise<void>

AI & Behavior Trees

Assertions for asserting enemy decision-making.

expect(aiController).toBeRunningBehaviorTree

Verifies the AI controller is actively running the specified Behavior Tree.
await expect(aiCon).toBeRunningBehaviorTree("/Game/AI/BT_Zombie");

Arguments

NameTypeDescription
treeClassPath stringThe behavior tree class path.
Returns:Promise<void>

expect(aiController).toHaveBlackboardValue

Verifies the AI's Blackboard has the expected value for the specified key.
await expect(aiCon).toHaveBlackboardValue("TargetActor", world.actor('Player'));

Arguments

NameTypeDescription
keyName stringThe blackboard key name.
expectedValue anyThe expected value for the key.
Returns:Promise<void>

expect(aiController).toHaveLineOfSightTo

Verifies the AI controller has line of sight to the specified actor.
await expect(aiCon).toHaveLineOfSightTo(world.actor('Player'));

Arguments

NameTypeDescription
otherActorLocator ActorLocatorThe locator of the target actor.
Returns:Promise<void>

Camera & FOV

Assertions for camera field of view, camera shakes, and view targets.

expect(actor).toHaveCameraFOV

Polls the actor's camera FOV until it matches the expected value within tolerance.
await expect(player).toHaveCameraFOV(90, { tolerance: 1.0 });

Arguments

NameTypeDescription
expectedFOV numberThe expected FOV angle in degrees.
options optionalObjectConfiguration object. Supports { tolerance?: number, timeout?: number }. Default tolerance: 0.5.
Returns:Promise<void>

expect(actor).toBeCameraShaking

Verifies the actor's PlayerCameraManager currently has active camera shakes. Supports .not negation.
// Assert camera is shaking after explosion
await expect(player).toBeCameraShaking();

// Assert camera is NOT shaking after it subsides
await expect(player).not.toBeCameraShaking();
Returns:Promise<void>

expect(actor).toHaveCameraViewTarget

Polls until the actor's camera view target matches the expected actor name.
await expect(player).toHaveCameraViewTarget('BP_PlayerCharacter');

Arguments

NameTypeDescription
actorName stringThe expected name of the camera's view target actor.
Returns:Promise<void>

AI Navigation

Assertions for AI pathfinding and navigation state.

expect(actor).toBeAINavigating

Verifies the actor's AI Controller is currently navigating along a path (PathFollowingStatus is Moving). Supports .not negation.
// Assert AI is navigating towards the player
await expect(aiPawn).toBeAINavigating();

// Assert AI has stopped navigating
await expect(aiPawn).not.toBeAINavigating();
Returns:Promise<void>

Team System

Assertions for the Generic Team Agent Interface.

expect(actor).toHaveTeamId

Polls until the actor's Generic Team ID matches the expected value.
await expect(player).toHaveTeamId(0);
await expect(spectator).not.toHaveTeamId(1);

Arguments

NameTypeDescription
expectedTeamId numberThe expected team ID (255 = NoTeam).
Returns:Promise<void>

expect(actor).toBeHostileTowards

Verifies the actor's team attitude towards another actor is Hostile. Supports .not negation.
await expect(player).toBeHostileTowards(enemy);
await expect(player).not.toBeHostileTowards(ally);

Arguments

NameTypeDescription
otherActor ActorLocatorThe other actor to evaluate attitude towards.
Returns:Promise<void>

State & Rendering

expect(actor).toHaveCount

Verifies that the locator resolves to exactly the expected number of elements in the engine.
await expect(world.actor('BP_Minion')).toHaveCount(5);

Arguments

NameTypeDescription
expectedCount numberThe expected number of matching elements.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toBeVisible

Verifies that the actor's 3D mesh was actively rendered on screen (inside the camera frustum and not completely occluded) on the last frame.
await expect(world.actor('BP_Minion_Range')).toBeVisible({ onScreen: true, timeout: 10_000 });

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { onScreen: boolean, timeout: number }.
Returns:Promise<void>

expect(actor).toBeInViewport

Verifies that the actor's 3D mesh or UMG widget element is actively rendered inside the active camera viewport frustum.
await expect(enemy).toBeInViewport();

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toBeDestroyed

Polls until the targeted actor is destroyed (marked PendingKill, destroyed, or garbage-collected from the UWorld). Supports .not negation to verify the actor remains alive/valid.
// Assert actor is destroyed after lethal damage
await expect(enemyKeep.locator).toBeDestroyed();

// Assert actor has NOT been destroyed
await expect(player).not.toBeDestroyed();

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toBeNiagaraActive

Verifies that a Niagara particle system component on the actor is currently active and emitting.
await expect(explosionEffect).toBeNiagaraActive();

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toHaveNiagaraAsset

Verifies that the actor's Niagara component is set to a specific Niagara system asset path.
await expect(fireVFX).toHaveNiagaraAsset("NS_Fire_Loop");

Arguments

NameTypeDescription
expectedAsset stringThe expected Niagara system asset path substring.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toBeAudioPlaying

Verifies that an Audio Component attached to the actor is actively playing sound.
await expect(footstepAudio).toBeAudioPlaying();

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toHaveSoundAsset

Verifies that the actor's Audio Component is playing a sound asset matching the specified name.
await expect(bgmAudio).toHaveSoundAsset("SoundWave_BossTheme");

Arguments

NameTypeDescription
expectedSound stringThe expected sound asset path or name substring.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toBePhysicsSimulating

Verifies that the actor's primitive or skeletal mesh is simulating physics (ragdoll).
await expect(deadEnemy).toBePhysicsSimulating({ boneName: "pelvis" });

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { boneName?: string, timeout?: number }.
Returns:Promise<void>

expect(actor).toBePhysicsAsleep

Verifies that a rigid body physics object has come to rest and entered sleep state.
await expect(crate).toBePhysicsAsleep();

Arguments

NameTypeDescription
options optionalObjectConfiguration object. Supports { boneName?: string, timeout?: number }.
Returns:Promise<void>

Enhanced Input (UE5)

Assertions for verifying active Input Mapping Contexts and Input Action values.

expect(actor).toHaveInputMappingContext

Verifies that an Enhanced Input Local Player Subsystem has a specific Input Mapping Context (IMC) applied.
await expect(player).toHaveInputMappingContext("IMC_DefaultPlayer");

Arguments

NameTypeDescription
contextNameOrPath stringThe IMC asset name or path.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toHaveInputActionValue

Verifies the current value of an Enhanced Input Action (IA).
await expect(player).toHaveInputActionValue("IA_Sprint", true);

Arguments

NameTypeDescription
actionNameOrPath stringThe Input Action name or path.
expectedValue anyThe expected action value (boolean, float, or Vector3).
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(actor).toHavePlayerScore

Verifies the player's current score on their PlayerState.
await expect(player).toHavePlayerScore(100, { operator: ">=" });

Arguments

NameTypeDescription
expectedScore numberThe expected score threshold.
options optionalObjectConfiguration object: { operator?: '>' | '<' | '>=' | '<=' | '===', timeout?: number }.
Returns:Promise<void>

UI & Widgets

Assertions for validating player HUDs or Menus.

expect(widget).toBeVisible

Directly queries the Slate rendering pipeline. Bypasses blueprint state and verifies if the widget was actively drawn to the screen on the last frame without occlusion.
const modal = world.widget("ConfirmPurchaseModal");
await expect(modal).toBeVisible();
Returns:Promise<void>

expect(widget).toBeEnabled

Verifies if the Slate widget is interactable (not disabled).
const submitBtn = world.widget("SubmitButton");
await expect(submitBtn).toBeEnabled();
Returns:Promise<void>

expect(widget).toHaveText

Polls the UTextBlock or URichTextBlock widget until its visible text matches the expected string.
const title = world.widget("HeaderTitle");
await expect(title).toHaveText("Main Menu");

Arguments

NameTypeDescription
expectedText stringThe exact expected text string.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(widget).toContainText

Polls the UTextBlock or URichTextBlock widget until its text contains the specified substring.
const subtitle = world.widget("WBP_Modal").getChild("SubtitleText");
await expect(subtitle).toContainText("cannot be undone");

Arguments

NameTypeDescription
substring stringThe substring to search for within the widget text.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>

expect(widget).toHaveValue

Polls the UEditableText or UEditableTextBox widget until its input value matches the expected string.
const usernameInput = world.widget("WBP_Login").getChild("UsernameInput");
await expect(usernameInput).toHaveValue("Player1");

Arguments

NameTypeDescription
expectedValue stringThe expected input string value.
options optionalObjectConfiguration object. Supports { timeout: number }.
Returns:Promise<void>