Skip to content

Add Playwright E2E testing setup#856

Draft
amcclain wants to merge 7 commits into
developfrom
atm/playwright-setup
Draft

Add Playwright E2E testing setup#856
amcclain wants to merge 7 commits into
developfrom
atm/playwright-setup

Conversation

@amcclain

Copy link
Copy Markdown
Member

Summary

Adds a standalone Playwright suite at playwright/ that drives a real running Toolbox instance against bootstrapped local test users — the foundation for systematic, Hoist-aware E2E coverage in this repo.

  • New playwright/ npm project (own package.json, tsconfig, node_modules). Ported from the JobSite suite. The hoist/ toolkit (HoistPage, GridHelper, FormHelper, ApiHelper) is deliberately app-agnostic — intended for eventual extraction into hoist-react or a @xh/hoist-testing package.
  • BootStrap.groovy creates test-admin@xh.io (granted HOIST_ADMIN) and test-user@xh.io in local dev when APP_TOOLBOX_TEST_USER_PASSWORD is set. Pair with APP_TOOLBOX_OAUTH_PROVIDER=NONE for the Hoist password login form.
  • User.groovy moves off the (now-removed) jasypt BasicPasswordEncryptor to the new io.xh.hoist.security.HoistPasswordEncoder.
  • Independent expert review of the harness, a design proposal for a dedicated component-scenario host sub-app, and a CHECKPOINT.md documenting the resume path — all under docs/playwright-port/.

5 specs green locally (2 auth setup + 3 smoke). Full setup, conventions, and hoist/ toolkit details in playwright/README.md.

Blocked on

hoist-core 41.0 — User.groovy uses HoistPasswordEncoder which is introduced in xh/hoist-core#568. Do not merge this branch until that ships. The hoist-core change removes the EOL jasypt-1.9.3 dependency that broke Toolbox bootstrap on JDK 21 + Spring Boot, which is what surfaced the original need for this work.

Test plan

  • Set APP_TOOLBOX_OAUTH_PROVIDER=NONE and APP_TOOLBOX_TEST_USER_PASSWORD=playwright-test in .env.
  • With hoist-core 41.0 published (or runHoistInline=true against xh/hoist-core#568), run ./gradlew :bootRun — confirm bootstrap reports Local test users configured for password-based login and no EncryptionInitializationException.
  • cd client-app && yarn start.
  • cd playwright && npm install && npm test — expect 5 passing (2 setup + 3 smoke).
  • Spot-check curl -s -c /tmp/auth.txt -X POST http://localhost:8080/xh/login -d 'username=test-admin@xh.io&password=playwright-test' returns success: true.

Notes

  • Branch contains the local dev runHoistInline flag at its default (false) — flip to true only locally for inline-Hoist verification.
  • docs/playwright-port/CHECKPOINT.md is the resume entrypoint if anyone (or any AI agent) picks this up cold.

🤖 Generated with Claude Code

amcclain and others added 2 commits May 26, 2026 22:10
Standalone playwright/ npm project that drives a real running Toolbox instance
against bootstrapped local test users. Ported from the JobSite suite with the
hoist/ toolkit deliberately app-agnostic (intended for eventual extraction into
hoist-react or @xh/hoist-testing). globalSetup.ts pre-flights both servers and
fails fast with an actionable message if either is missing.

Includes docs/playwright-port/ with the project log, an independent expert
review of the harness, a design proposal for a future component-scenario host
sub-app, and a CHECKPOINT.md describing the resume path.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
BootStrap creates test-admin@xh.io (granted HOIST_ADMIN via RoleService) and
test-user@xh.io in local dev when APP_TOOLBOX_TEST_USER_PASSWORD is set. Pair
with APP_TOOLBOX_OAUTH_PROVIDER=NONE for the Hoist password login form used by
the Playwright suite.

User.groovy moves off the (now-removed) jasypt BasicPasswordEncryptor to
io.xh.hoist.security.HoistPasswordEncoder. Requires hoist-core 41.0+ - do not
merge this branch before hoist-core 41.0 ships.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
amcclain and others added 5 commits May 27, 2026 08:29
The wholesale `systemProperties System.properties` forward overrode the toolchain
JVM's own `java.home` (and friends) with the Gradle daemon's, causing the forked
JDK 21 process to resolve its internal ICU/JCE resources against an unrelated JDK
install — surfacing as `NoClassDefFoundError: NormalizerBase$NFCModeImpl` on any
crypto operation when daemon JDK != toolchain JDK.

Per-dev settings belong in `.env`, where Spring Boot's relaxed env-var binding
picks them up (e.g. `SERVER_PORT=8081` -> `server.port`).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Replaces a broken `RoleService.ensureRequiredConfigAndRolesCreated` override
that called `Role.save()` outside any Hibernate session (RoleService.init does
not open one), throwing `HibernateException: No Session found for current
thread` and aborting RoleService.init mid-flight.

New shape mirrors the established pattern from sibling Hoist apps: BootStrap
injects `roleService`, creates the test users via `ensureTestUsersCreated`,
runs `parallelInit(services)` so RoleService is ready, then calls
`grantTestUserRoles()` which uses `roleService.assignRole(user, name)` (the
@transactional path through DefaultRoleUpdateService). `test-user@xh.io` is
intentionally left without any role so the suite can exercise unprivileged paths.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds PR568_VERIFICATION_FINDING.md capturing the manual smoke test against the
hoist-core jasypt removal branch, including the local repro for the unrelated
build.gradle JDK-mismatch bug that the verification surfaced (fixed separately).

Also scrubs a reference to non-public XH app names from JASYPT_REMOVAL_REPORT.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
… to bootRun

The wholesale `systemProperties System.properties` forward overrode the toolchain
JVM's own `java.home` (and similar JDK-install descriptors) with the Gradle daemon's,
causing the forked toolchain JDK 21 process to resolve its internal modules against
an unrelated JDK install — surfacing as `NoClassDefFoundError: NormalizerBase$NFCModeImpl`
on any code path that touches ICU (regex normalization, JCE init, java.text.Normalizer)
when daemon JDK != toolchain JDK.

Narrows the forward to skip those specific properties while preserving the
documented bootRun flags (`-Dserver.port=8081`, `-Duser.timezone=Etc/UTC`,
`-Dserver.ssl.*`, etc. - see README.md).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@lbwexler lbwexler mentioned this pull request Jun 18, 2026
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