Step-by-Step Migration Walkthrough
Here is the exact step-by-step path to upgrade a v2 project to v3:1. Update the Gradle Plugin Version
In yourbuild.gradle.kts, bump the plugin version to 3.0.0 (or check for the latest 3.x release):
2. Update package.json and Install
In src/test/e2e/package.json, replace @drownek/plugwright with @plugwright/runner using version ^3.0.0 (or matching your Gradle plugin’s 3.x version), then run npm install:
3. Update Spec Imports
In your TypeScript test files, rename the package import:4. Run gradlew plugwrightTest
Run your test task:
- Moves your
*.spec.tsfiles fromsrc/test/e2e/intosrc/test/e2e/tests/(preserving subdirectories). - Updates
src/test/e2e/tsconfig.jsonto include"tests/**/*.ts"and"plugins/**/*.ts". - Compiles the tests and runs the suite.
Recommended Configuration Update
While v3 retains compatibility with the old flatplugwright { ... } block, it is recommended to adopt the new environments syntax. Notice that server-specific settings (minecraftVersion, acceptEula, downloadPlugins) now belong inside environments.create("local", LocalMode):
Without
environments, the flat properties define an implicit local environment. They are deprecated and slated for removal.API Adjustments & Modernizations
Awaiting server.execute(...)
In v3, server.execute(...) communicates with the console channel asynchronously and returns a Promise<string>.
While unawaited calls will often still fire in the background (similar to v2 behavior), awaiting it is strongly recommended so you can catch errors or read command output reliably:
GUI Item Display Name Property
Instead of invokingitem.getDisplayName(), you can now use the clean property accessor item.displayName:
Built-in player.clearInventory(...)
Avoid manual command workarounds to reset a player’s inventory. player.clearInventory clears the inventory and waits until client-side inventory state reflects it:
Directory & Git Ignore Updates
The runtime directories are now isolated per environment:- Server files: Now live in
<testsDir>/generated/<environment>/run/(e.g.src/test/e2e/generated/local/run/). - Compiled specs: Output to
src/test/e2e/dist/.
src/test/e2e/.gitignore contains:
run/ from your repository’s top-level .gitignore if it’s no longer used.
New Features Available in v3
Plugwright v3 brings major capabilities designed for real-world server environments, race condition detection, and complex gameplay flows:1. Stateful Multi-Step Tests: describe.serial
By default, every test gets a fresh player and an isolated connection. With describe.serial, a single player connection is maintained across all tests in the block. This makes it effortless to test lifecycles such as kit cooldowns, auction cycles, multi-step quests, and economy balances without cumbersome workarounds.
createPlayer({ as: 'buyer' }). Read more in Writing Tests › describe.serial.
2. Race Condition Testing: concurrency: N
Catching bugs like item duping, chest snipe, or auction desync requires multiple players hitting the same logic simultaneously. Plugwright v3 introduces first-class concurrency at the test and serial block level:
3. Remote Stands & External Servers (ExternalMode)
In addition to spinning up ephemeral local Paper servers via LocalMode, v3 natively supports testing against remote staging servers, production mirrors, or persistent local stands using ExternalMode.
- Account Pools: Safely leases and releases pre-configured test bot accounts.
- RCON Console Channel: Execute server commands and parse console responses via secure RCON.
- Stand Reset & Ping Tasks: Auto-generated
./gradlew <env>Pingand./gradlew <env>Cleantasks.
4. Runner Plugins & Authentication (e.g. AuthMe)
Runner plugins extend test execution with custom hooks, fixtures, matchers, and auth adapters. Plugwright v3 provides first-party packages like@plugwright/auth-authme (handling login/register dialogs, session resumption, and password secrecy).
Plugins can be declared directly in your Gradle environment configuration:
5. Private npm Registries
If your organization distributes internal matchers, runner plugins, or fixtures via private npm registries, declare them right in yourbuild.gradle.kts:
.npmrc scoped configuration automatically before installing test dependencies. Read more in Configuration.