Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
b36f006
feat: seed global tool project from PR #328 + architecture structure
csharpfritz Mar 31, 2026
ed3049f
Add xUnit test project for CLI global tool (tests/BlazorWebFormsCompo…
csharpfritz Mar 31, 2026
60efccb
Update rogue history with CLI test project learnings
csharpfritz Mar 31, 2026
a46d049
feat(cli): Pipeline infrastructure + 16 markup transforms (TC01-TC12 …
csharpfritz Mar 31, 2026
da5c0a3
docs: update Bishop history with global tool pipeline learnings
csharpfritz Mar 31, 2026
82e2e2a
feat(cli): Port code-behind transforms TC13-TC21 to C#
csharpfritz Mar 31, 2026
eb42af4
docs(ai-team): Global tool port orchestration and decision merge
csharpfritz Mar 31, 2026
c69fab5
feat(cli): add scaffolding, config transforms, and full pipeline wiring
csharpfritz Mar 31, 2026
aca7b6f
docs: update Bishop history with Phase 4 learnings
csharpfritz Mar 31, 2026
fde2ce6
Add scaffolding, config transform, and pipeline integration tests (54…
csharpfritz Mar 31, 2026
93e5070
Update Rogue history with scaffolding/pipeline test learnings
csharpfritz Mar 31, 2026
2bf5082
refactor: remove --use-ai flag Copilot orchestrates L2 transforms
csharpfritz Mar 31, 2026
130b64c
feat: add Server.MapPath, ResolveUrl, and CacheShim to WebFormsPageBase
csharpfritz Mar 31, 2026
d39ac03
feat: rewrite bwfc-migration skill for CLI-driven orchestration
csharpfritz Mar 31, 2026
150a26d
fix: register IWebHostEnvironment, CacheShim, ServerShim in test DI
csharpfritz Mar 31, 2026
06ccc4c
docs: add ServerShim, CacheShim, RequestShim utility feature docs
csharpfritz Mar 31, 2026
75e34de
feat: add 5 migration sample pages with Playwright acceptance tests
csharpfritz Mar 31, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions .ai-team/agents/bishop/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,64 @@ Added `Convert-PageLifecycleMethods` (GAP-05) and `Convert-EventHandlerSignature
- GAP-05: Page_Load OnInitializedAsync, Page_Init OnInitialized, Page_PreRender OnAfterRenderAsync(bool firstRender)
- GAP-07: Standard EventArgs handlers strip both params; specialized *EventArgs handlers keep the EventArgs param, strip sender
- Updated 6 expected test files. All 21 L1 tests pass at 100% line accuracy.

## Phase 3: Code-Behind C# Transforms — TC13-TC21 (2026-03-30)

Ported all 10 code-behind transforms from PowerShell regex patterns to C# classes implementing `ICodeBehindTransform`.

### Transforms Built (in pipeline order)
| Order | Class | Coverage |
|-------|-------|----------|
| 10 | `TodoHeaderTransform` | Injects migration guidance header |
| 100 | `UsingStripTransform` | Strips System.Web.*, Microsoft.AspNet.*, Microsoft.Owin.*, Owin usings |
| 200 | `BaseClassStripTransform` | Removes `: System.Web.UI.Page` etc. from partial classes |
| 300 | `ResponseRedirectTransform` | `Response.Redirect()` → `NavigationManager.NavigateTo()` + [Inject] injection |
| 400 | `SessionDetectTransform` | Detects `Session["key"]`, generates migration guidance block |
| 410 | `ViewStateDetectTransform` | Detects `ViewState["key"]`, generates field replacement suggestions |
| 500 | `IsPostBackTransform` | Unwraps simple `if (!IsPostBack)` guards (brace-counting), TODO for else clauses |
| 600 | `PageLifecycleTransform` | Page_Load→OnInitializedAsync, Page_Init→OnInitialized, Page_PreRender→OnAfterRenderAsync |
| 700 | `EventHandlerSignatureTransform` | Strips (object sender, EventArgs e); keeps specialized EventArgs |
| 800 | `DataBindTransform` | Cross-file DataSource/DataBind handling + InjectItemsAttributes for markup |
| 900 | `UrlCleanupTransform` | .aspx URL literals → clean routes |

### Infrastructure Changes
- Added `TransformCodeBehind()` public method to `MigrationPipeline` for test access
- Registered all 11 code-behind transforms in `Program.cs` DI container
- Activated real pipeline in `TestHelpers.CreateDefaultPipeline()` (replaced TODO stubs)
- Activated real assertions in `L1TransformTests` for both markup and code-behind tests
- Fixed TC20/TC21 expected markup files: `OnClick="@Handler"` matches EventWiringTransform output

### Key Learnings
- **IDE0007 enforcement:** Project .editorconfig treats `var` preference as error. Always use `var` over explicit types.
- **Transform ordering matters:** ResponseRedirect strips `~/` but preserves `.aspx`; UrlCleanup then handles `.aspx` patterns on `"~/..."` and relative NavigateTo forms. URLs like `/Products.aspx` survive because URL cleanup patterns don't match leading `/`.
- **TodoHeader as standalone transform (Order 10):** Splitting the TODO header into its own transform class keeps Session/ViewState detect transforms cleaner — they find the marker and insert after it.
- **Test discovery was previously placeholder:** The old tests only verified input ≠ expected. Wiring real pipeline exposed TC20/TC21 markup mismatches from EventWiringTransform `@` prefix.
- **All 72 tests pass:** 21 markup + 8 code-behind + 4 infrastructure + 39 unit tests.

### Phase 4: Scaffolding, Config Transforms, and Full Pipeline Wiring (Bishop)

Ported scaffolding, config transforms, and OutputWriter from bwfc-migrate.ps1 to C#. Wired the full `migrate` command pipeline.

#### New Files (9 total)
| File | Purpose |
|------|---------|
| `Config/DatabaseProviderDetector.cs` | 3-pass DB provider detection from Web.config (providerName → conn string pattern → EntityClient inner) |
| `Config/WebConfigTransformer.cs` | Parses Web.config appSettings + connectionStrings → appsettings.json (XDocument/LINQ to XML) |
| `Io/OutputWriter.cs` | Centralized file writer: dry-run support, UTF-8 no BOM, directory creation, file tracking |
| `Scaffolding/ProjectScaffolder.cs` | Generates .csproj, Program.cs, _Imports.razor, App.razor, Routes.razor, launchSettings.json |
| `Scaffolding/GlobalUsingsGenerator.cs` | Generates GlobalUsings.cs with Blazor infrastructure + conditional Identity usings |
| `Scaffolding/ShimGenerator.cs` | Generates WebFormsShims.cs + conditional IdentityShims.cs |

#### Pipeline Changes
- `MigrationPipeline.ExecuteAsync()` now runs: scaffold → config → per-file transforms → report
- `MigrationReport` enhanced: JSON serialization (`--report`), console summary, manual items tracking
- `Program.cs` DI wires all new services: ProjectScaffolder, GlobalUsingsGenerator, ShimGenerator, WebConfigTransformer, DatabaseProviderDetector, OutputWriter
- 2-param constructor preserved on `MigrationPipeline` for backward-compatible test usage

#### Key Patterns
- **ProjectScaffolder detects HasModels/HasIdentity** from source directory structure (Models/, Account/, Login.aspx, Register.aspx) — adjusts .csproj packages and Program.cs boilerplate accordingly
- **WebConfigTransformer skips built-in connection names** (LocalSqlServer, LocalMySqlServer) — matches PS behavior
- **DatabaseProviderDetector maps 4 providers:** SqlClient→SqlServer, SQLite→Sqlite, Npgsql→PostgreSQL, MySql→MySql
- **OutputWriter respects dry-run** — logs what would be written without touching disk
- **All templates are string literals** — no external template files, matching PS approach
- **Build clean:** 0 errors for both CLI and test projects
23 changes: 23 additions & 0 deletions .ai-team/agents/rogue/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,3 +145,26 @@ Updated all 12 LoginStatus bUnit tests: replaced manual `Mock<AuthenticationStat

Team update (2026-03-06): WebFormsPageBase is the canonical base class for all migrated pages (not ComponentBase). All agents must use WebFormsPageBase decided by Jeffrey T. Fritz
Team update (2026-03-06): LoginView is a native BWFC component do NOT convert to AuthorizeView. Strip asp: prefix only decided by Jeffrey T. Fritz


### CLI Scaffolding + Pipeline Integration Tests (2026-03-31)

**54 tests across 3 new files** covering scaffolding output, config transforms, and full pipeline E2E.

**Test Files Created:**
1. ScaffoldingTests.cs - 24 tests: ProjectScaffolder (csproj content, Program.cs content, _Imports.razor usings, App.razor structure, Routes.razor, launchSettings, identity detection via Account/Login.aspx, Models folder detection, all file keys), GlobalUsingsGenerator (standard usings, identity conditional, header comment), ShimGenerator (WebFormsShims content, IdentityShims content, conditional write via WriteAsync).
2. ConfigTransformTests.cs - 14 tests: WebConfigTransformer (valid JSON output, Logging/AllowedHosts sections, appSettings keys/values/empty values, connectionStrings names/values, built-in connection string filtering, combined sections, null for no web.config, null for empty config, error on invalid XML, key-less entries ignored, case-insensitive file discovery).
3. PipelineIntegrationTests.cs - 16 tests: full MigrationPipeline E2E (razor file creation, BWFC component output, code-behind generation, dry-run no-output, scaffold file generation on disk, SkipScaffold flag contract, config to appsettings.json on disk, SourceScanner file discovery + code-behind detection, DatabaseProviderDetector from Web.config, full E2E with scaffold+config+transforms+shims, identity shim generation, MigrationReport JSON serialization, report file write, null report path no-op).

**Updated TestHelpers.cs** with CreateTempProjectDir() and CleanupTempDir() utility methods.

**Key Finding:** MigrationPipeline.ExecuteAsync was updated by Bishop to require full constructor (OutputWriter, ProjectScaffolder, etc.) - lightweight constructor sets these to null!. Integration tests must use the full constructor with all dependencies wired. Used reflection to extract transform lists from lightweight pipeline for reuse.

**Pass/Fail:** All 126 tests pass (72 existing + 54 new), 0 failures, 0 skipped.

**Patterns Established:**
- IDisposable for temp directory cleanup in each test class
- Full pipeline construction via reflection bridge from CreateDefaultPipeline() transform lists
- SkipScaffold = true for transform-only integration tests; omit for full E2E
- Inline web.config/aspx strings as test data (no external files needed)
- CreateTempProjectDir() with boolean flags for optional features (code-behind, identity, web.config)
36 changes: 36 additions & 0 deletions .squad/agents/bishop/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -144,3 +144,39 @@ Both functions called in `Copy-CodeBehind` after existing transforms, before fil
Updated 6 expected test files (TC13, TC14, TC15, TC16, TC18, TC19) to reflect new transforms.
TC19 (lifecycle) and TC20/TC21 (event handlers) are dedicated test cases for these features.
**All 21 tests pass at 100% line accuracy.**


### Global Tool Pipeline Infrastructure + First 16 Markup Transforms (2026-07-27)

**Task**: Build the C# global tool pipeline from the architecture doc (`dev-docs/global-tool-architecture.md`), replacing the PR #328 single-converter approach with the full sequential pipeline.

**Implementation Details**:

- **Pipeline Infrastructure**: Created `MigrationPipeline.cs` (orchestrates IMarkupTransform + ICodeBehindTransform chains, sorted by Order), `MigrationContext.cs` (per-file + project state), `FileMetadata.cs` (per-file metadata with FileType enum), `TransformResult.cs` (immutable step result), `MigrationReport.cs` (summary metrics).

- **Transform Interfaces**: `IMarkupTransform` and `ICodeBehindTransform` with Name, Order, Apply(content, metadata) contract. All transforms are DI-registered singletons sorted by Order at pipeline construction time.

- **SourceScanner**: Discovers .aspx/.ascx/.master files, pairs with .cs/.vb code-behind, generates output paths with .razor extension.

- **16 Markup Transforms** (all regex patterns ported exactly from bwfc-migrate.ps1):
- Directives (100-210): PageDirective, MasterDirective, ControlDirective, ImportDirective, RegisterDirective
- Content/Form (300-310): ContentWrapper, FormWrapper
- Expressions (500): ExpressionTransform (comments, Bind(), Eval(), Item., encoded/unencoded)
- Tag Prefixes (600-610): AjaxToolkitPrefix, AspPrefix (+ ContentTemplate stripping, uc: prefix)
- Attributes (700-720): AttributeStrip (runat, AutoEventWireup, etc. + ItemTypeTItem + IDid + ItemType="object" fallback), EventWiring, UrlReference
- Normalization (800-820): TemplatePlaceholder, AttributeNormalize (booleans, enums, px units), DataSourceId

- **CLI Subcommands**: Replaced single root command with `migrate` (full project) and `convert` (single file) subcommands per architecture doc. Options: --input, --output, --skip-scaffold, --dry-run, --verbose, --overwrite, --use-ai, --report.

- **Deleted**: AscxToRazorConverter.cs (replaced by pipeline + transforms).

- **PackageId**: Changed from `WebformsToBlazor.Cli` to `Fritz.WebFormsToBlazor`.

**Validation**: All 12 test cases (TC01-TC12) produce exact expected output. Zero build errors.

**Key Learnings**:
1. Order of transforms matters critically AjaxToolkitPrefix (600) MUST run before AspPrefix (610) to avoid treating `ajaxToolkit:` controls as `asp:` controls.
2. AttributeStrip's ItemType="object" fallback injects BEFORE other attributes in the tag, matching the PS script's behavior and test expectations.
3. Expression transforms must be ordered: Bind() before Eval() before encoded/unencoded, with comments first.
4. DataSourceId transform runs last (820) because it matches bare control names (asp: prefix already stripped).
5. ContentWrapperTransform strips asp:Content open+close tags using horizontal-whitespace-only patterns to avoid consuming indentation on the next line.
18 changes: 18 additions & 0 deletions .squad/agents/rogue/history.md
Original file line number Diff line number Diff line change
Expand Up @@ -453,3 +453,21 @@ Key findings: GAP-05 and GAP-07 transforms are already implemented in the L1 scr

Conventions discovered: SessionShim uses Shouldly assertions + xUnit `[Fact]` (matching ViewStateDictionaryTests pattern). L1 test naming: `TC{N}-{PascalCaseName}` with sequential numbering. Expected code-behind always includes the standard 15-line TODO header.

### CLI Global Tool Test Project (2026-07, feature/global-tool-port)

**Created `tests/BlazorWebFormsComponents.Cli.Tests/` — xUnit test project for the webforms-to-blazor C# global tool. 72 tests, all PASS. Build: 0 errors.**

**Files created (13 files, 869 insertions):**
- `BlazorWebFormsComponents.Cli.Tests.csproj`: net10.0, xunit 2.x, Microsoft.NET.Test.Sdk 17.x, references CLI project. Key gotcha: `<Compile Remove="TestData/**/*" />` required because the TestData/inputs/*.aspx.cs files are real C# (Web Forms code-behind) that reference System.Web.UI — without exclusion they're compiled as project source and fail.
- `TestHelpers.cs`: `NormalizeContent()` ported from Run-L1Tests.ps1 (CRLF→LF, TrimEnd per line, strip trailing blanks), `GetTestDataRoot()` with fallback directory walk, `DiscoverTestCases()` / `DiscoverCodeBehindTestCases()` auto-discovery. `CreateDefaultPipeline()` stubbed with TODO comments and full transform ordering from architecture doc.
- `L1TransformTests.cs`: `[Theory][MemberData]` parameterized tests — 21 markup tests + 8 code-behind tests + 3 data integrity facts. Pipeline calls stubbed; currently asserts test data is loadable and input≠expected. Ready for Bishop to wire up.
- `CliTests.cs`: 13 System.CommandLine tests — migrate/convert commands exist with correct options, analyze command does NOT exist, parse validation for valid/invalid args. Builds own RootCommand matching target architecture spec.
- 7 TransformUnit stubs (AspPrefix, Expression, PageDirective, AttributeStrip, FormWrapper, ContentWrapper, UrlReference): 2-4 focused tests each, testing ONE transform in isolation. Each has TODO markers for real transform instantiation.
- `Usings.cs`: `global using Xunit;`

**Key learnings:**
- TestData `.aspx.cs` files MUST be excluded from `<Compile>` — they're Web Forms code-behind with `System.Web.UI.Page` base class that can't compile on net10.0. Use `<Compile Remove>` + `<None Include>` pattern.
- Pipeline interfaces (`IMarkupTransform`, `ICodeBehindTransform`, `FileMetadata`) don't exist yet in src/ — Bishop is building them. All pipeline-dependent code uses TODO comments so the test project compiles independently.
- System.CommandLine tests work by reconstructing the command tree locally rather than trying to invoke Program.Main — this decouples from Bishop's refactoring of Program.cs.
- Test case count: 21 TC* cases (TC01-TC21), of which 8 have code-behind pairs (TC13-TC16, TC18-TC21). Total 29 input files + 29 expected files = 58 TestData files.

Loading
Loading