| name | webforms-characterization |
| description | Use this skill to capture the current behavior of an ASP.NET WebForms workflow before any refactoring begins. Produces Playwright E2E tests and/or golden-master approval tests that act as the migration oracle. Invoke before extracting business logic from any VB event handler.
|
| argument-hint | [workflow/page name] [critical validations] [DB/SOAP dependencies] [test environment URL] |
WebForms Characterization Skill
When to Use
- Before refactoring or extracting any VB event handler.
- Before rebuilding a WebForms page in ASP.NET Core.
- When you need to confirm that a change has not broken existing behavior.
Prerequisite
- A running instance of the legacy WebForms application (local or test environment).
- A test database with representative data OR the ability to seed data before each test run.
- A test SOAP endpoint OR an agreed stub/fake for SOAP-backed workflows.
Procedure
1. Workflow Discovery
Identify for the target page/workflow:
- URL and entry point
- Form fields: names, types, required/optional, validation rules visible in UI
- User actions: button clicks, dropdowns, auto-complete, tabbed sections
- Expected outputs: what appears on success, what validation errors look like
- Conditional behavior: what shows/hides depending on data or user role
2. Test Plan (document before writing code)
For each workflow, produce a test plan table:
Test ID | Scenario | Input | Expected Output | Covers Rule
T01 | Happy path | valid data | success message | Main submission
T02 | Required field missing | empty name | "Name is required" | Validation
T03 | Invalid format | "abc" in phone | format error | Input format guard
T04 | Edge case | max-length input | accepted or truncated | Boundary
3. Playwright E2E Test Structure
import { test, expect } from '@playwright/test';
test.describe('[WorkflowName] — characterization', () => {
test.beforeEach(async ({ page }) => {
await page.goto('/path/to/legacy-page.aspx');
});
test('T01 — happy path submission', async ({ page }) => {
await page.fill('#ctl00_MainContent_txtName', 'Test User');
await page.selectOption('#ctl00_MainContent_ddlType', 'Standard');
await page.click('#ctl00_MainContent_btnSubmit');
await expect(page.locator('#ctl00_MainContent_lblResult')).toContainText('Success');
});
test('T02 — required field validation', async ({ page }) => {
await page.click('#ctl00_MainContent_btnSubmit');
await expect(page.locator('.validation-summary')).toBeVisible();
});
});
4. Approval Tests for Expression Evaluator / Transformation Module
using Verify = VerifyXunit.Verifier;
public class ExpressionEvaluatorApprovalTests
{
[Fact]
public async Task Evaluate_TypicalInput_MatchesSnapshot()
{
var evaluator = new ExpressionEvaluator();
var result = evaluator.Evaluate("INPUT_EXPRESSION", testData);
await Verify(result);
}
[Theory]
[InlineData("", null)]
[InlineData("EXPR_MAX_LENGTH")]
[InlineData("EXPR_ZERO_VAL")]
public async Task Evaluate_EdgeCases_MatchSnapshot(string input) { ... }
}
5. Coverage Checklist
Before declaring characterization complete:
Output
- Committed test files in
/tests/E2E/ and /tests/Unit/ or /tests/Approval/
- A
CHARACTERIZATION_STATUS.md for the workflow listing: covered scenarios, gaps, and oracle reliability rating (High/Medium/Low)