Paper E2E v1.1.0
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 byplayer.gui({ title }).player.waitForGuiItem(predicate): Replaced bygui.locator(predicate).player.clickGuiItem(predicate): Replaced bygui.locator(predicate).click().GuiWrapper.findItem/findAllItems: Replaced byGuiItemLocator.