You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
fix: wait for Blazor circuit before form interaction in tests
The WebFormsForm Playwright tests were racing against Blazor Server
circuit establishment. During prerendering, the form renders without
@onsubmit:preventDefault, so clicking submit before the circuit is
ready causes a full-page POST that resets component state.
Changes:
- Add data-interactive attribute to WebFormsForm when in interactive mode
- Wait for form[data-interactive] in tests before filling/submitting
- Tighten input locators to match actual field names (username, email)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copy file name to clipboardExpand all lines: .squad/agents/cyclops/history.md
+9Lines changed: 9 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -987,3 +987,12 @@ foreach (var warning in warnings) {
987
987
-`@onsubmit:preventDefault` prevents default form submission in interactive mode
988
988
989
989
**Build:** ✅ 0 errors on net8.0;net9.0;net10.0
990
+
991
+
### Playwright Locator Fix for WebFormsFormTests (2025-07-15)
992
+
993
+
**Summary:** Fixed two failing Playwright tests in `WebFormsFormTests.cs` where locators were matching the always-visible migration guidance card instead of the actual results card.
- Demo pages use `data-audit-control` attributes prefixed with the component name, e.g. `webforms-form-results` not just `form-results`.
997
+
- Always use the exact `[data-audit-control='...']` selector in Playwright tests rather than fuzzy text-based locators like `text=Request.Form` or `:has-text()`, which can match unrelated visible sections.
998
+
- When a section is conditionally rendered (e.g., gated by `@if (isPostBack)`), the test locator must target that specific section's attribute, not generic text that may appear elsewhere on the page.
# Decision: FormShim wraps IFormCollection with null-safe degradation
2
+
3
+
**Author:** Cyclops
4
+
**Date:** 2026-07-31
5
+
**Status:** Implemented
6
+
7
+
## Context
8
+
9
+
Migrated Web Forms code-behind frequently uses `Request.Form["fieldName"]` to read POST data. The existing `RequestShim` had `Cookies`, `QueryString`, and `Url` but no `Form`.
10
+
11
+
## Decision
12
+
13
+
Created `FormShim` as a public class (not an interface implementation) that wraps `IFormCollection?` and provides `NameValueCollection`-like API. The `RequestShim.Form` property follows the same graceful degradation pattern as `Cookies`:
14
+
15
+
1.**SSR mode (HttpContext available):** wraps `HttpContext.Request.Form` via `FormShim`
3.**Interactive mode (no HttpContext):** logs warning once → returns empty `FormShim(null)`
18
+
19
+
## Why not implement IFormCollection?
20
+
21
+
`FormShim` targets `NameValueCollection` semantics (Web Forms API), not `IFormCollection` (ASP.NET Core API). The indexer, `GetValues()`, `AllKeys` surface matches what migrated code actually calls. Implementing `IFormCollection` would add unnecessary API surface and file upload concerns.
22
+
23
+
## Impact
24
+
25
+
- Unblocks any migrated code-behind that reads `Request.Form["key"]`
26
+
- No breaking changes — new property on existing class
# Decision: SSR Opt-Out Pattern via ExcludeFromInteractiveRouting
2
+
3
+
**Author:** Cyclops
4
+
**Date:** 2025-07-24
5
+
**Status:** Implemented
6
+
7
+
## Context
8
+
9
+
The sample app uses `@rendermode="InteractiveServer"` on `<Routes>` in `App.razor`, meaning all pages run interactively via SignalR. Pages that need real HTTP POST (like the Request.Form demo) can't function because there's no form data in interactive mode.
10
+
11
+
## Decision
12
+
13
+
Modified `App.razor` to use `HttpContext.AcceptsInteractiveRouting()` for conditional render mode assignment. Pages that need SSR add `@attribute [ExcludeFromInteractiveRouting]` — the standard Microsoft pattern for .NET 8+.
14
+
15
+
**Impact:** This is non-breaking. All existing pages continue as InteractiveServer. Only pages explicitly decorated with the attribute will render as SSR.
16
+
17
+
## Applies To
18
+
19
+
Any future sample page or migration demo that needs real HTTP request/response semantics (form POSTs, Request.Form, Request.Cookies during POST, etc.) should use this same attribute.
0 commit comments