# Tests: create-ui-page

Six tests to verify the skill activates correctly, produces valid output, and enforces invariants.

---

## Test 1: Skill activates on trigger phrases

**Setup:** User says: "Create a UI for the Visit reschedule flow."

**Expected:** Agent invokes the `create-ui-page` skill (not `create-process`, not `create-business-object`).

**Pass criteria:**

-   The skill is invoked before any file is written.
-   Agent checks whether the target BO (`RescheduleVisitBo` or similar) exists before writing the UI.
-   If BO is missing, agent invokes `create-business-object` first.

**Fail if:** Agent writes a `.userinterface.xml` file without checking for the prerequisite BO/LO or process.

---

## Test 2: Dialog page creation (SingleSectionDialogPage)

**Setup:** User says: "Create a dialog UI for the Call_Reschedule process that lets the user pick a new start date and time."

**Expected output file:** `src/Call/PR/Call_Reschedule/Call_RescheduleUI.userinterface.xml`

**Pass criteria:**

-   Root element: `<UIDescription name="Call::RescheduleUI" schemaVersion="0.0.0.5">`
-   `pagePattern="SingleSectionDialogPage"` with `onBackDiscard="true"`
-   `<PageHeader>` contains a `<MenuItem directlyVisible="true">` with a `<ButtonPressedEvent>`
-   `<Resource>` elements have non-empty `id` and `defaultLabel`
-   `<DatePickerField>` + `<TimePickerField>` inside a `<Merger>` for date/time input
-   All `<Binding target="Value">` paths follow `ProcessContext::<BoDeclName>.<prop>` pattern
-   `schemaVersion="0.0.0.5"` present

**Fail if:**

-   File placed in a `UI/` subfolder instead of `PR/Call_Reschedule/`
-   `schemaVersion` is `"1.1"` (that's for BOs/LOs, not UIs)
-   Any `defaultLabel` is empty string or absent
-   `<ButtonPressedEvent event>` value is not checked against the sibling process

---

## Test 3: List page creation (SingleSectionPage + GroupedList)

**Setup:** User says: "Create a list overview screen for the Visit_VisitList process, showing visits from LoVisit with name and planned date columns."

**Expected output file:** `src/Visit/PR/Visit_VisitList/Visit_VisitListUI.userinterface.xml`

**Pass criteria:**

-   `pagePattern="SingleSectionPage"` (not `SingleSectionDialogPage`)
-   `<Area areaPattern="SingleElementArea">` contains a `<GroupedList>`
-   `dataSource` ends in `.Items[]` with **capital I**
-   `<Items name="Items">` wraps `<ItemListLayout>` and `<Bindings>` (not placed directly in the list)
-   `<ItemListLayout>` defines at least `<Default>` layout with `Col`/`Row` elements
-   `<Bindings>` inside `<Items>` uses `ONE_WAY` mode for all display fields
-   `<ItemSelectedEvent>` passes at least `pKey`

**Fail if:**

-   `dataSource="ProcessContext::LoVisit.items[]"` (lowercase `i`)
-   `<Bindings>` placed directly inside `<GroupedList>` rather than inside `<Items>`
-   `bindingMode="TWO_WAY"` on list item display bindings

---

## Test 4: Detail page creation (SingleSectionPage + GroupedElementsArea)

**Setup:** User says: "Create an editable detail screen for the Order_OrderDetail process, bound to BoOrder with fields for customerName, status (dropdown), and notes."

**Expected output file:** `src/Order/PR/Order_OrderDetail/Order_OrderDetailUI.userinterface.xml`

**Pass criteria:**

-   `pagePattern="SingleSectionPage"`
-   `<Area areaPattern="GroupedElementsArea">` with at least one `<GroupElement>`
-   `customerName` → `<InputArea>` with `bindingMode="TWO_WAY"`
-   `status` → `<SelectionBox>` with a `toggleId` on the DataSource `<Binding>` and `bindingMode="TWO_WAY"` on the Value `<Binding>`
-   `notes` → `<InputAreaMultiLine>` with `bindingMode="TWO_WAY"`
-   Save button `<MenuItem>` with `<ButtonPressedEvent>` wired to a process action

**Fail if:**

-   `<SelectionBox>` missing the `<Binding target="DataSource" toggleId="...">` binding
-   `bindingMode="TWO_WAY"` on a `disabled="true"` field (should be `ONE_WAY`)
-   Group section header `defaultLabel` is empty or missing

---

## Test 5: Binding mismatch detection

**Setup:** Agent is writing a UI where the process declares `ProcessContext::RescheduleVisitBo` but
the UI template uses `ProcessContext::rescheduleVisitBo` (lowercase `r`).

**Expected:** Agent catches the discrepancy during cross-check of the sibling process file and
corrects the binding path before writing the file.

**Pass criteria:**

-   The final written file uses the exact ProcessContext variable name from the process `<Declarations>`.
-   No `<Binding>` path uses a variable name that is not declared in the process.

**Fail if:** Agent writes the UI without checking the sibling process and the binding path doesn't
match the declared variable name.

---

## Test 6: No forbidden content (MFG audit)

**Setup:** Review the generated skill files and any UI output created by this skill.

**Pass criteria:**

```bash
grep -rni "mfg" .claude/skills/create-ui-page/ \
  --include="*.md" --include="*.template" | grep -v "Forbidden\|MFG check" || echo "NO MFG"
```

Output should be `NO MFG`.

**Fail if:** Any skill file or template references "MFG", "MfgVisit", "MfgQuality", or any
MFG-specific module name. Skill files must use only real shipping modules:
Visit, Order, Product, Tour, Call, Promotion, Customer Issue, Workflow.
