feat: add end-to-end test suite (Aspire + Playwright)#78
Merged
Conversation
Add tests/AndreGoepel.AppFoundation.E2ETests, a browser-driven E2E suite that boots the sample AppHost graph (Postgres + MailHog + sample web app) via Aspire.Hosting.Testing and drives it with Playwright (Chromium). 25 tests across setup, registration + email confirmation, login/lockout/logout, password reset, TOTP 2FA, passkeys (WebAuthn via CDP virtual authenticator), account management, administration, and the foundation admin pages. - Reuses the sample AppHost as-is (resource web, MailHog http endpoint); MailHog captures email for confirmation/reset assertions. - Central Package Management: adds Aspire.Hosting.Testing, Microsoft.Playwright, Otp.NET; project opts out of lock files (RID-specific Aspire orchestration). - CI: main test job excludes E2E; new e2e.yml workflow runs it with Docker. - Adds podman.runsettings and README for local runs.
The suite never went green: the first CI run failed 16/25 and, once the infra issues were peeled back, a real application bug surfaced. Application fix - MailService.SmtpEmailSender and MailSettingsProvider (plus the IMailSettingsProvider / MailConfiguration they expose) were internal, so Wolverine 6 refused to generate the MailMessage handler (ServiceLocationPolicy.NotAllowed) and every outgoing email was silently discarded after its retries. Making them public restores email delivery for registration, password reset, and confirmation across the app. Test-infrastructure fixes - AppHost: resolve MailHog's SMTP host/port at run time instead of hardcoding localhost:1025, so email works under the Aspire testing host (which assigns random proxy ports); run Postgres without its data volume when E2E=true so each run starts from an empty database. - Sample host opts into self-service registration (as a real host would) so the registration flows are reachable. - MailHogClient: only quoted-printable-decode a part that declares that transfer encoding (unconditional decoding corrupted confirmation URLs whose "=" was followed by two hex digits), and guard null MIME/Content. - Login helper retries the submit click (a click can be lost on a cold Blazor circuit); admin provisioning reloads-and-retries on first-request warmup. Test corrections - NonAdmin admin-area test asserts the user is bounced off /Administration (the app sends an authenticated non-admin to home, not to login). - Passkey-login test accepts conditional-mediation auto-login, which preempts the explicit button click. Full suite: 25/25 green.
andregoepel
force-pushed
the
feature/e2e-tests
branch
from
July 12, 2026 03:28
b1cf522 to
4a8924b
Compare
andregoepel
added a commit
to andregoepel/marten-identity
that referenced
this pull request
Jul 12, 2026
Adds tests/AndreGoepel.Marten.Identity.E2ETests — a browser-driven suite that boots the sample Aspire graph (PostgreSQL + the sample web app) via Aspire.Hosting.Testing and drives it with Playwright (Chromium). 24 tests cover setup/bootstrap, registration + email confirmation, login/lockout/logout, password reset + resend, TOTP 2FA (enable/login/recovery/disable), passkeys (WebAuthn via a CDP virtual authenticator), account management, administration, and the sample pages. Modelled on andregoepel/app-foundation#78, since those account/administration pages originate from this repo's Blazor package. Harness: - One app instance per collection; fresh browser context per test; root admin provisioned once via /Setup (idempotent). Otp.NET for TOTP, CDP virtual authenticator for passkeys. Radzen/Blazor-aware helpers centralise selectors and the circuit-ready wait. - The AppHost runs Postgres without its data volume under E2E=true, so every run starts from an empty database. - The sample sends no real email. Under E2E=true it swaps LoggingEmailSender for a CapturingEmailSender and exposes an E2E-only /e2e/emails endpoint that the tests read for confirmation/reset links; both are inert in a normal run. Integration: - Central Package Management: adds Aspire.Hosting.Testing, Microsoft.Playwright, and Otp.NET. The project opts out of lock files (RestorePackagesWithLockFile =false) because Aspire.Hosting.Testing pulls RID-specific packages; locked-mode restore still passes solution-wide. - CI: the main test job excludes E2E (--filter FullyQualifiedName!~E2ETests); a new e2e.yml runs the suite with Docker + Playwright. - Formatted with the pinned csharpier. Verified: all 24 tests pass against a live Podman runtime.
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.
Closes #76
Adds
tests/AndreGoepel.AppFoundation.E2ETests— a browser-driven end-to-end suite that boots the sampleAppHostgraph (PostgreSQL + MailHog + the sample web app) via Aspire.Hosting.Testing and drives it with Playwright (Chromium).Coverage (25 tests)
Setup/bootstrap · registration + email confirmation · login/lockout/logout · password reset + resend · TOTP 2FA (enable/login/recovery/disable) · passkeys (WebAuthn via CDP virtual authenticator) · account management (profile/password/delete) · administration (users/roles/authorization) · foundation admin pages (Email Settings, Login Features) · sample home.
Harness
web, MailHoghttpendpoint). MailHog's HTTP API is read for confirmation/reset-link assertions./Setup(idempotent).Otp.NETfor TOTP, CDP virtual authenticator for passkeys.Integration with the restructured repo
Aspire.Hosting.Testing,Microsoft.Playwright,Otp.NETtoDirectory.Packages.props; the project references packages without versions.RestorePackagesWithLockFile=false) because Aspire.Hosting.Testing pulls RID-specific orchestration packages — same rationale as the sample AppHost. Verifieddotnet restore --locked-modestill passes for the whole solution.dotnet list package --vulnerableclean); formatted with the pinned csharpier.--filter FullyQualifiedName!~E2ETests); newe2e.ymlruns the suite with Docker + Playwright.podman.runsettings+ README for local runs.Note
Compiles and all 25 tests are discovered, but the suite has not yet been executed against a live container runtime. The account-flow pages now come from the
AndreGoepel.Marten.Identity.BlazorNuGet package, so those selectors should be confirmed on the first live run (Docker or a running Podman machine).