Skip to content

Add an end-to-end test suite that runs the plugin on a real server - #75

Merged
milanmalhotra merged 15 commits into
devfrom
issue-34-e2e-test-harness
Aug 22, 2026
Merged

Add an end-to-end test suite that runs the plugin on a real server#75
milanmalhotra merged 15 commits into
devfrom
issue-34-e2e-test-harness

Conversation

@milanmalhotra

Copy link
Copy Markdown
Collaborator

Closes #34

Adds a second test suite that runs the built jar on a real Paper 1.21.11 server and drives it with real player bots. src/main is untouched.

What's here

  • The harness. An E2E-only build.gradle.kts plus the committed wrapper. Gradle is a test runner and nothing else; Maven still builds the only artifact. Plugwright boots Paper, stages the newest jar out of target/, and joins Mineflayer bots.
  • Seven tests covering all six acceptance criteria: the plugin loads and creates its SQLite database, home creation persists and lists, /home teleports (asserted on the bot's actual position, not just the chat message), the GUI opens with the configured title, clicking a home teleports, and an unprivileged player is refused and writes nothing.
  • A nightly e2e.yml workflow, separate from tests.yml so every push stays fast.
  • A changeset-gate exemption for the E2E build files. The gate fails closed and would otherwise demand a user-facing changelog entry for test infrastructure.
  • A developer guide. src/README.md had been .changeset/README.md until it was moved into src/ verbatim, so it documented only the changeset workflow. It now covers prerequisites, the build, the local server, both test suites and the pull request conventions, with the changeset documentation kept in place.

No changeset: nothing here changes behavior for server owners.

Running it

mvn -B clean package -DskipTests
./gradlew plugwrightTest

Maven has to go first, since Gradle stages the newest jar out of target/ rather than building one. Local runs on this branch: end-to-end 7 passed / 0 failed in 1.4s, unit suite 389 passed / 0 skipped.

Two things to know before merging

  • The nightly is inert on dev. GitHub only fires schedule triggers for workflows on the default branch, so e2e.yml will not run nightly until it reaches master. workflow_dispatch still works by hand in the meantime.
  • boot.spec.ts cannot see the plugin's own errors. The plugin logs through Bukkit.getLogger(), so its lines carry no SH2 prefix and the test's filter drops them. It still catches Paper's load and enable failures, the likeliest regression for a shaded jar, but it would stay green through a swallowed database error. Filed as Plugin messages go to the root logger, so its errors carry no SH2 prefix and cannot be filtered #74 rather than patched here, since the honest fix is a src/main change.

toHaveReceivedMessage without since scans the whole per-test message
buffer, which the earlier create-home reply had already populated
with a string containing base. The assertion passed even when
list-homes printed nothing.
Paper renders levels as [Thread/ERROR], not the SEVERE token the old
regex looked for, and Bukkit.getLogger() is the root logger so a
plugin error carries the SH2 prefix from plugin.yml rather than the
plugin name. Both gaps let a real plugin error through the filter
silently. Match the actual level token and accept either the plugin
name or the SH2 prefix, keeping the existing load-failure phrases.
The fixture staged inventoryTitle as Your homes, byte-identical to the
plugin's shipped default, so a regression that hardcoded the default
and dropped the config lookup would still pass every title assertion.
Stage E2E homes instead and update the matching assertions.
A hung Paper download, npm install, or bot connect would otherwise
burn the 360 minute GitHub default unattended. The per-test timeout
already covers individual tests; this bounds boot and downloads too.
The file was .changeset/README.md until it was moved to src/ verbatim, so it
documented only the changeset workflow and nothing about building or testing.

It now covers prerequisites, the build, the local Paper server, both test
suites and the pull request conventions, with the changeset documentation kept
in place. The bump section now says patch rather than offering a choice, which
is what the project actually does.
Replaces the nightly schedule with a pull_request trigger. Work pools on dev
between releases, so master can sit unchanged for weeks and the schedule mostly
re-ran an identical commit. The drift a nightly existed to catch, the Paper
download, the pinned anvilgui snapshot and the npm toolchain, surfaces on the
next pull request anyway, which is when it matters.

Still not on every push: the suite pays server boot before its first assertion,
which is wasted on a branch with no pull request open yet.

workflow_dispatch is kept. The concurrency group now cancels a superseded run
when a pull request is pushed to again, rather than keeping a manual dispatch
from queueing alongside the schedule.
Comments that only defended a decision are gone: the workflow header arguing
against a schedule, the note justifying the log upload step, the preamble on
the changeset exemption test, and the aside on the gradle/ prefix. The rest
are trimmed to the constraint a reader cannot see from the code.

Also corrects boot.spec.ts. The comment said a plugin-logged error carries the
SH2 prefix from plugin.yml. That prefix belongs to the plugin's own getLogger();
the plugin logs through Bukkit.getLogger(), the root logger, whose lines carry
neither token, so the filter sees Paper's load and enable failures and not the
plugin's own errors. The comment now says that.

No behavior changes.
CLAUDE.md is not tracked in the repo, so the guide cannot point at it for
anything a contributor needs.

The paragraph introducing it as a third doc is gone. The note on reading
Skipped: 0 pointed there for the mechanism, so the mechanism is now stated in
place: MockBukkit's UnimplementedOperationException extends JUnit's
TestAbortedException, a skip rather than a failure, and FailOnUnimplemented on
ServerTestBase converts those aborts back into failures.
@milanmalhotra
milanmalhotra merged commit 93b17a4 into dev Aug 22, 2026
6 checks passed
@milanmalhotra
milanmalhotra deleted the issue-34-e2e-test-harness branch August 22, 2026 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant