class: SpecterWorld

The SpecterWorld class provides methods to interact with the Unreal Engine instance. It is the primary fixture passed to every test, equivalent to the page fixture in Playwright.

Connection & Lifecycle

SpecterWorld.connect

Static factory method that connects to an Unreal Engine instance over WebSockets and returns a new SpecterWorld fixture.
const world = await SpecterWorld.connect();

Arguments

NameTypeDescription
url optionalstringThe WebSocket URL (Default: 'ws://127.0.0.1:8080').
Returns:Promise<SpecterWorld>

world.joinHost

Commands the local client to join a multiplayer host/server via IP.
await world.joinHost("192.168.1.100", "Arena_P");

Arguments

NameTypeDescription
ipAddress stringThe server IP address.
expectedMap optionalstringWait for this map to load after joining.
Returns:Promise<void>

world.close

Closes the WebSocket connection to the engine.
await world.close();
Returns:Promise<void>

world.cleanup

Destroys all actors that were dynamically spawned during the test via world.spawnActor().
await world.cleanup();
Returns:Promise<void>

World & Level Management

world.loadMap

Synchronously loads a level. Supports advanced options like game modes and listen servers.
await world.loadMap("/Game/Maps/Arena", { listen: true });

Arguments

NameTypeDescription
mapName stringThe map name or path.
options optionalLoadMapOptionsConfiguration object.
Returns:Promise<void>

world.waitForMapLoad

Waits for a specific map to be loaded.
await world.waitForMapLoad("Arena");

Arguments

NameTypeDescription
mapName stringThe map to wait for.
timeout optionalnumberTimeout in ms (Default: 15000).
Returns:Promise<void>

world.currentMap

Property getter for the currently loaded map name.
console.log(world.currentMap);
Returns:string

world.getNetworkStatus

Retrieves the current network mode and server address.
const status = await world.getNetworkStatus();
Returns:Promise<{ netMode: string, map: string, serverAddress: string }>

world.spawnActor

Synchronously spawns an actor of the given class into the world.
const boss = await world.spawnActor('/Game/Blueprints/Enemies/BP_Boss');

Arguments

NameTypeDescription
assetPath stringThe blueprint class path to spawn.
options optionalSpawnOptionsConfiguration object containing location, rotation, and properties.
Returns:Promise<ActorLocator>

Global Engine Execution

world.evaluate

Executes a global C++ plugin command.
await world.evaluate("TakeScreenshot", { fileName: "menu" });

Arguments

NameTypeDescription
commandName stringThe command to execute.
payload optionalobjectCommand payload.
context optionalstringTest runner UI context.
targetLocator optionalstringTarget locator string.
Returns:Promise<any>

world.console

Executes a raw Unreal Engine console command.
await world.console("cheat god");

Arguments

NameTypeDescription
commandString stringThe console command.
Returns:Promise<void>

world.setTimeScale

Fast-forward through long animation sequences or slow down physics during testing. Unifies with time dilation and reports to Playwright step logs.
await world.setTimeScale(2.0);

Arguments

NameTypeDescription
multiplier numberThe time scale multiplier (e.g. 2.0 for 2x speed).
Returns:Promise<void>

world.setTimeDilation

Adjusts the global time dilation of the engine. Unifies with time scale and reports to Playwright step logs.
await world.setTimeDilation(0.5);

Arguments

NameTypeDescription
multiplier numberThe time dilation multiplier (e.g. 0.5 for half speed).
Returns:Promise<void>

world.takeScreenshot

Captures a screenshot of the active Unreal Engine viewport.
const path = await world.takeScreenshot("inventory_open", true);

Arguments

NameTypeDescription
fileName stringThe name of the saved file.
showUI optionalbooleanRender the UMG UI layer (Default: false).
Returns:Promise<string>

world.waitForVariable

Waits for an arbitrary global engine variable to reach a specific value.
await world.waitForVariable("GameState.Phase", "Combat");

Arguments

NameTypeDescription
varName stringThe variable name.
expectedValue stringThe expected value.
timeout optionalnumberTimeout in ms (Default: 5000).
Returns:Promise<SpecterTimelineEvent>

world.waitForEvent

Natively waits for a C++ UObject delegate to broadcast on the world context (e.g. mapLoaded, playerJoined, actorSpawned). Supports predicate filtering.
// Custom timeout & predicate options
await world.waitForEvent('playerJoined', {
    timeout: 10000,
    predicate: (data) => data.playerName === 'Player_1'
});

Arguments

NameTypeDescription
eventName stringThe name of the world event to bind to.
optionsOrPredicate optionalFunction | ObjectA predicate function (payload) => boolean, or an options object { timeout, predicate }.
Returns:Promise<any>

Input Simulation

Methods for simulating hardware input globally across the active game viewport.

world.keyboard.press

Simulates a raw hardware key press globally.
// Option 1: Press and hold the key for 2000ms (2 seconds) before releasing
await world.keyboard.press('E', 2000);

Arguments

NameTypeDescription
key stringThe UE key name (e.g. 'E', 'SpaceBar').
holdMs optionalnumberHow long to hold the key before releasing it (in milliseconds).
Returns:Promise<void>

world.keyboard.down

Manually holds a key down indefinitely.
// Option 2: Manually hold the key down indefinitely (e.g., walking forward)
await world.keyboard.down('W');
await world.waitForEvent('SomeEvent'); // Wait for something to happen while walking
await world.keyboard.up('W'); // Release it

Arguments

NameTypeDescription
key stringThe UE key name.
Returns:Promise<void>

world.keyboard.up

Releases a manually held key.
await world.keyboard.up('W');

Arguments

NameTypeDescription
key stringThe UE key name.
Returns:Promise<void>

world.injectAxis

Injects a raw analog value directly into the PlayerController's InputAxis method. Useful for simulating fine analog movements like slightly tilting a gamepad thumbstick or partially pulling a trigger.
// Push the left thumbstick 50% forward for one frame
await world.injectAxis('Gamepad_LeftY', 0.5);

Arguments

NameTypeDescription
axisName stringThe name of the axis binding (e.g. 'Gamepad_LeftY').
value numberThe float value to inject (typically -1.0 to 1.0).
Returns:Promise<void>

world.playSequence

Plays a mathematically accurate frame-by-frame SpecterInputSequence applied globally to the engine's active game viewport.
import { SpecterInputSequence } from '@specter/test';

const spinAttack = new SpecterInputSequence()
    .addAxisCircle('Gamepad_LeftX', 'Gamepad_LeftY', 0, 1500, 2);

await world.playSequence(spinAttack);

Arguments

NameTypeDescription
sequence SpecterInputSequenceThe input sequence to play.
options optionalObject{ loops?: number } The number of times to loop the sequence.
Returns:Promise<void>

Locator Factories

Methods for querying objects in the engine. These return lazy-evaluated Locators.

world.actor

Queries actors by Blueprint class name, or by Gameplay Tag using a 'Tag:' or 'tag=' prefix selector.
// By Class Name (Default)
const player = world.actor("BP_Hero");

// By Gameplay Tag Prefix Selector (Playwright-style)
const boss = world.actor("Tag:Enemy.Boss");
const bossAlt = world.actor("tag=Enemy.Boss");

Arguments

NameTypeDescription
selector stringClass name (e.g. 'BP_Hero') or tag prefix selector (e.g. 'Tag:Enemy.Boss' or 'tag=Enemy.Boss').
Returns:ActorLocator

world.actorByTag

Queries actors by their Gameplay Tag.
const enemy = world.actorByTag("Enemy.Boss");

Arguments

NameTypeDescription
tagName stringThe tag name.
Returns:ActorLocator

world.widget

Queries UMG widgets by their Blueprint class name.
const inventory = world.widget("WBP_Inventory");

Arguments

NameTypeDescription
className stringThe class name.

world.getByPlayerId

Queries for the possessed pawn of a specific Player ID.
const p1 = world.getByPlayerId(0);

Arguments

NameTypeDescription
playerId numberThe player ID.
Returns:ActorLocator

world.subsystem

Queries a UEngineSubsystem, UGameInstanceSubsystem, or ULocalPlayerSubsystem.
const audio = world.subsystem("AudioSubsystem");

Arguments

NameTypeDescription
subsystemName stringThe subsystem class name.

world.uobject

Queries for a generic UObject in memory by its class name.
const saveGame = world.uobject("MySaveGame");

Arguments

NameTypeDescription
className stringThe object class name.

Performance Profiling

Real-time engine performance metrics for benchmarking and regression testing.

world.getPerformanceMetrics

Retrieves real-time performance metrics from the engine including FPS (from world delta time), frame time in ms, and used physical memory in MB.
const metrics = await world.getPerformanceMetrics();
console.log(`FPS: ${metrics.fps}`);
console.log(`Frame Time: ${metrics.frameTimeMs}ms`);
console.log(`Memory: ${metrics.memoryMb}MB`);

// Assert minimum performance threshold
expect(metrics.fps).toBeGreaterThan(30);
Returns:Promise<{ fps: number, frameTimeMs: number, memoryMb: number }>

AI & Navigation (Global)

Global NavMesh queries that are not tied to a specific actor.

world.isPointReachable

Runs a synchronous NavMesh path query via UNavigationSystemV1 to determine if a path exists between two world positions.
const reachable = await world.isPointReachable(
  { x: 100, y: 200, z: 0 },
  { x: 500, y: 600, z: 0 }
);
expect(reachable).toBe(true);

Arguments

NameTypeDescription
start Vector3The starting world coordinate.
end Vector3The destination world coordinate.
Returns:Promise<boolean>

Sequencer & Cutscenes

Control and query Level Sequence (cutscene) playback state.

world.isSequencePlaying

Checks if a Level Sequence Actor is currently playing. Auto-discovers sequence by name match.
const playing = await world.isSequencePlaying('IntroSequence');

Arguments

NameTypeDescription
sequenceName stringThe name of the Level Sequence Actor.
Returns:Promise<boolean>

world.getSequencePlaybackPosition

Returns current playback position of a Level Sequence in seconds.
const pos = await world.getSequencePlaybackPosition('IntroSequence');
console.log(`Cutscene is at ${pos}s`);

Arguments

NameTypeDescription
sequenceName stringThe name of the Level Sequence Actor.
Returns:Promise<number>

world.scrubSequence

Scrubs the Level Sequence to an exact time position in seconds using EUpdatePositionMethod::Scrub.
// Jump to the 5-second mark of the intro cutscene
await world.scrubSequence('IntroSequence', 5.0);

// Verify the cutscene spawned a specific actor at that moment
await expect(world.actor('BP_CutsceneBoss')).toBeVisible();

Arguments

NameTypeDescription
sequenceName stringThe name of the Level Sequence Actor.
positionSeconds numberThe target time position in seconds.
Returns:Promise<void>

Network & Lag Emulation

Methods available on world.network to simulate real-world multiplayer conditions.

world.network.setEmulatedLatency

Simulates network ping/latency on the active client connection.
await client1.network.setEmulatedLatency(150);

Arguments

NameTypeDescription
pingMs numberTarget latency in milliseconds (e.g. 150).
Returns:Promise<void>

world.network.setPacketLoss

Simulates packet loss percentage on the active client network connection.
await client1.network.setPacketLoss(5);

Arguments

NameTypeDescription
lossPercent numberPacket loss percentage from 0 to 100 (e.g. 5).
Returns:Promise<void>

world.network.resetNetworkEmulation

Resets emulated latency and packet loss back to 0.
await client1.network.resetNetworkEmulation();
Returns:Promise<void>

Interfaces

SpawnOptions

interface SpawnOptions {
  tag?: string;
  location?: Vector3;
  rotation?: Rotator;
  properties?: Record<string, any>;
  spawnController?: boolean;
}

LoadMapOptions

interface LoadMapOptions {
  gameMode?: string;
  listen?: boolean;
}