Docs Menu
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
| Name | Type | Description |
|---|---|---|
| url optional | string | The 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
| Name | Type | Description |
|---|---|---|
| ipAddress | string | The server IP address. |
| expectedMap optional | string | Wait 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
| Name | Type | Description |
|---|---|---|
| mapName | string | The map name or path. |
| options optional | LoadMapOptions | Configuration object. |
Returns:Promise<void>
world.waitForMapLoad
Waits for a specific map to be loaded.
await world.waitForMapLoad("Arena");Arguments
| Name | Type | Description |
|---|---|---|
| mapName | string | The map to wait for. |
| timeout optional | number | Timeout 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
| Name | Type | Description |
|---|---|---|
| assetPath | string | The blueprint class path to spawn. |
| options optional | SpawnOptions | Configuration 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
| Name | Type | Description |
|---|---|---|
| commandName | string | The command to execute. |
| payload optional | object | Command payload. |
| context optional | string | Test runner UI context. |
| targetLocator optional | string | Target locator string. |
Returns:Promise<any>
world.console
Executes a raw Unreal Engine console command.
await world.console("cheat god");Arguments
| Name | Type | Description |
|---|---|---|
| commandString | string | The 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
| Name | Type | Description |
|---|---|---|
| multiplier | number | The 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
| Name | Type | Description |
|---|---|---|
| multiplier | number | The 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
| Name | Type | Description |
|---|---|---|
| fileName | string | The name of the saved file. |
| showUI optional | boolean | Render 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
| Name | Type | Description |
|---|---|---|
| varName | string | The variable name. |
| expectedValue | string | The expected value. |
| timeout optional | number | Timeout 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
| Name | Type | Description |
|---|---|---|
| eventName | string | The name of the world event to bind to. |
| optionsOrPredicate optional | Function | Object | A 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
| Name | Type | Description |
|---|---|---|
| key | string | The UE key name (e.g. 'E', 'SpaceBar'). |
| holdMs optional | number | How 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 itArguments
| Name | Type | Description |
|---|---|---|
| key | string | The UE key name. |
Returns:Promise<void>
world.keyboard.up
Releases a manually held key.
await world.keyboard.up('W');Arguments
| Name | Type | Description |
|---|---|---|
| key | string | The 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
| Name | Type | Description |
|---|---|---|
| axisName | string | The name of the axis binding (e.g. 'Gamepad_LeftY'). |
| value | number | The 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
| Name | Type | Description |
|---|---|---|
| sequence | SpecterInputSequence | The input sequence to play. |
| options optional | Object | { 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
| Name | Type | Description |
|---|---|---|
| selector | string | Class 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
| Name | Type | Description |
|---|---|---|
| tagName | string | The tag name. |
Returns:ActorLocator
world.widget
Queries UMG widgets by their Blueprint class name.
const inventory = world.widget("WBP_Inventory");Arguments
| Name | Type | Description |
|---|---|---|
| className | string | The class name. |
Returns:WidgetLocator
world.getByPlayerId
Queries for the possessed pawn of a specific Player ID.
const p1 = world.getByPlayerId(0);Arguments
| Name | Type | Description |
|---|---|---|
| playerId | number | The player ID. |
Returns:ActorLocator
world.subsystem
Queries a UEngineSubsystem, UGameInstanceSubsystem, or ULocalPlayerSubsystem.
const audio = world.subsystem("AudioSubsystem");Arguments
| Name | Type | Description |
|---|---|---|
| subsystemName | string | The subsystem class name. |
Returns:SpecterLocator
world.uobject
Queries for a generic UObject in memory by its class name.
const saveGame = world.uobject("MySaveGame");Arguments
| Name | Type | Description |
|---|---|---|
| className | string | The object class name. |
Returns:SpecterLocator
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
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
| Name | Type | Description |
|---|---|---|
| sequenceName | string | The 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
| Name | Type | Description |
|---|---|---|
| sequenceName | string | The 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
| Name | Type | Description |
|---|---|---|
| sequenceName | string | The name of the Level Sequence Actor. |
| positionSeconds | number | The 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
| Name | Type | Description |
|---|---|---|
| pingMs | number | Target 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
| Name | Type | Description |
|---|---|---|
| lossPercent | number | Packet 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;
}