Skip to content

Paper E2E v1.1.0

Choose a tag to compare

@Drownek Drownek released this 10 Feb 18:49
6ca9b52

This release introduces a new reactive architecture for GUI testing, significantly improving stability when testing asynchronous inventory updates. It also adds a suite of player management utilities and improved assertion logic.

Highlights

Reactive GUI API

The framework has transitioned from a snapshot-based model to a live handle model. Previous versions relied on GuiWrapper, which captured the inventory state at a single moment in time. Version 1.1.0 introduces LiveGuiHandle and GuiItemLocator.

  • Live Handles: The new player.gui({ title }) method returns a handle that maintains a reference to the currently open container. It remains valid even as items within the inventory change.
  • Locators: Items are now defined by query logic rather than direct reference. Locators allow tests to define an item (e.g., by name or lore) and interact with it regardless of when it appears in the inventory.
  • Automatic Retries: Interactions such as .click() and assertions now automatically wait and retry until the condition is met or a timeout is reached. This eliminates flaky tests caused by server-tick delays.

Player Lifecycle Utilities

Common administrative tasks have been standardized into the PlayerWrapper class to reduce boilerplate code in test setups:

  • player.makeOp() / player.deOp()
  • player.setGameMode(mode)
  • player.teleport(x, y, z)
  • player.giveItem(item, count)

Changes

New API Usage

The following example demonstrates the new locator pattern compared to the legacy approach.

// New Pattern
test('admin can toggle settings', async ({ player }) => {
  await player.chat('/admin menu');
  
  // 1. Get a live handle (does not resolve items immediately)
  const menu = await player.gui({ title: /Settings/ });
  
  // 2. Define a locator
  const toggleBtn = menu.locator(item => item.name === 'lever');
  
  // 3. Assertions automatically wait for the item to appear and match the state
  await expect(toggleBtn).toHaveLore('Status: OFF');
  
  // 4. Click automatically waits for the item to be clickable
  await toggleBtn.click();
  
  // 5. Re-use the same locator to verify the state change
  await expect(toggleBtn).toHaveLore('Status: ON');
});

Deprecations

The snapshot-based API is now deprecated. These methods will continue to function in v1.1.0 but will emit console warnings and will be removed in a future major release.

  • player.waitForGui(predicate): Replaced by player.gui({ title }).
  • player.waitForGuiItem(predicate): Replaced by gui.locator(predicate).
  • player.clickGuiItem(predicate): Replaced by gui.locator(predicate).click().
  • GuiWrapper.findItem / findAllItems: Replaced by GuiItemLocator.