Add Playwright E2E testing setup#856
Draft
amcclain wants to merge 7 commits into
Draft
Conversation
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>
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>
This reverts commit 83d171f.
… 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>
Closed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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.playwright/npm project (ownpackage.json,tsconfig,node_modules). Ported from the JobSite suite. Thehoist/toolkit (HoistPage,GridHelper,FormHelper,ApiHelper) is deliberately app-agnostic — intended for eventual extraction into hoist-react or a@xh/hoist-testingpackage.BootStrap.groovycreatestest-admin@xh.io(grantedHOIST_ADMIN) andtest-user@xh.ioin local dev whenAPP_TOOLBOX_TEST_USER_PASSWORDis set. Pair withAPP_TOOLBOX_OAUTH_PROVIDER=NONEfor the Hoist password login form.User.groovymoves off the (now-removed) jasyptBasicPasswordEncryptorto the newio.xh.hoist.security.HoistPasswordEncoder.CHECKPOINT.mddocumenting the resume path — all underdocs/playwright-port/.5 specs green locally (2 auth setup + 3 smoke). Full setup, conventions, and
hoist/toolkit details inplaywright/README.md.Blocked on
hoist-core 41.0 — User.groovy uses
HoistPasswordEncoderwhich is introduced in xh/hoist-core#568. Do not merge this branch until that ships. The hoist-core change removes the EOLjasypt-1.9.3dependency that broke Toolbox bootstrap on JDK 21 + Spring Boot, which is what surfaced the original need for this work.Test plan
APP_TOOLBOX_OAUTH_PROVIDER=NONEandAPP_TOOLBOX_TEST_USER_PASSWORD=playwright-testin.env.runHoistInline=trueagainst xh/hoist-core#568), run./gradlew :bootRun— confirm bootstrap reportsLocal test users configured for password-based loginand noEncryptionInitializationException.cd client-app && yarn start.cd playwright && npm install && npm test— expect 5 passing (2 setup + 3 smoke).curl -s -c /tmp/auth.txt -X POST http://localhost:8080/xh/login -d 'username=test-admin@xh.io&password=playwright-test'returnssuccess: true.Notes
runHoistInlineflag at its default (false) — flip totrueonly locally for inline-Hoist verification.docs/playwright-port/CHECKPOINT.mdis the resume entrypoint if anyone (or any AI agent) picks this up cold.🤖 Generated with Claude Code