AAA Game Automation.
Modern Developer Experience.

Bring modern software testing practices directly into Unreal Engine. Specter bridges UE5 directly to Node via WebSockets, empowering your SDETs to build robust, code-driven test suites in TypeScript from day one.

charge.spec.tsREADY
import { test, expect } from '@specter/test'

test("Q - Charge should move Steel forward and apply damage", async ({
    server: {
      heroes: { steel },
      minion,
    },
    steelActor,
  }) => {
    const enemySpawnLocations: Vector3[] = [
      { x: -412.950478, y: 441.416008, z: 160.0 },
      { x: -412.950478, y: 231.416008, z: 160.0 },
      { x: -582.950478, y: 301.416008, z: 160.0 },
    ];

    const enemies = await test.step("Spawn enemies", async () => {
      return await Promise.all(
        enemySpawnLocations.map((location) =>
          minion.spawn({
            theme: "paragon",
            type: "range",
            spawnOptions: {
              location,
              properties: { InitialTeamId: 2 },
              rotation: { pitch: 0, yaw: -90, roll: 0 },
            },
          }),
        ),
      );
    });

    const startLocation = await steelActor.getLocation();
    const forwardDirection = await steelActor.getForwardVector();
    await steelActor.triggerAbilityWithTarget(
      steel.abilityCharge,
      VectorUtils.addOffset(startLocation, forwardDirection, 50),
    );

    await test.step("Verify hit enemies recieve damage and knockback", async () => {
      await Promise.all([
        ...enemies.flatMap((enemy, index) => [
          expect(enemy).toHaveGameplayTag("Status.Stunned"),
          expect(enemy).toHaveAttributeChange("HealthSet", "Health", {
            delta: -100,
          }),
          expect(enemy).toHaveMovedFurtherThan(enemySpawnLocations[index], 100),
        ]),
      ]);
    });

    await expect(steelActor).toHaveMovedFurtherThan(startLocation, 1000);
  });

See It In Action

Watch how perfectly our Playwright game-object model syncs with native Unreal Engine execution.

90% Less Boilerplate.
100% Native Execution.

Say goodbye to brittle, massive C++ test harnesses. Specter introduces the Game Object Model—giving your SDETs strongly-typed access to native actors and abilities directly from TypeScript.

The Native Reality

For contrast, look at the code on the right. This is the exact same test written natively in Unreal's Gauntlet framework using C++.

Manual cast fetching, brittle latent command queuing, zero IntelliSense for objects... this is what costs studios millions of dollars in SDET velocity.

Visual Debugging

In-Engine Test Explorer & Playwright UI

No context switching. Specter includes a native Unreal Editor Utility Widget that embeds the Playwright test runner directly inside UE5. Run test suites, stream live frame telemetry, and debug step failures without ever leaving the editor.

Native UE5 Editor Utility Widget acting as Playwright UI inside Unreal Engine
Live step telemetry, green/red status indicators, and console log streaming
Full compatibility with Playwright UI mode & HTML Trace Viewers for CI/CD
In-Engine Trace Viewer Preview
See Full Features