Skip to main content
The API uses live handles and locators, inspired by Playwright, for reactive and reliable GUI interactions.

Quick Start

Core Concepts

Live Handles vs Snapshots

Live Handle (LiveGuiHandle) - Always reflects the player’s current GUI state:
  • Returned by player.gui({ title })
  • Automatically updates when GUI changes
  • Use for dynamic, reactive testing
Snapshot (GuiWrapper) - Captures GUI state at a specific moment:
  • Legacy API, now deprecated
  • Use live handles for new code

Locators

Locators are queries that re-evaluate each time they’re used:

Modern API

player.gui({ title, timeout? })

Gets a live handle to a GUI matching the title pattern.
string | RegExp
required
Pattern to match GUI title.
number
Max wait time in ms (default: 5000).
Returns: LiveGuiHandle Examples:

gui.locator(predicate)

Creates a locator for items matching the predicate.
function
required
(item: ItemWrapper) => boolean
Returns: GuiItemLocator Examples:

locator.click(options?)

Clicks the located item with automatic retry.
number
Max wait time in ms (default: 5000ms).
Examples:

locator.displayName()

Gets the display name of the located item (re-queries each call).

locator.loreText()

Gets the lore text of the located item (re-queries each call).

expect(locator).toHaveLore(text, options?)

Asserts that a locator’s item contains specific lore text, with automatic retry.
string
required
Text that should appear in lore.
number
Max wait time in ms (default: 5000ms).
number
Check interval in ms (default: 100ms).
Examples:

gui.title

Gets the current GUI title (or undefined if closed).

Complete Examples

Permission Test

Item Interaction

Dynamic Lore Testing

Paginated GUIs

Legacy API (Deprecated)

The following methods are deprecated. Use the modern API instead.
  • player.waitForGui(guiMatcher, options?) -> Use player.gui({ title })
  • gui.findItem(predicate) -> Use gui.locator(predicate)
  • gui.clickItem(predicate) -> Use gui.locator(predicate).click()

Tips

  • GUI operations are async - always use await
  • Locators are reactive - they re-query on each use
  • Use expect(locator).toHaveLore() for dynamic content
  • Custom display names differ from Minecraft item names
  • Check logs if GUI doesn’t open - the command might have failed