Set up AI dev environment for recordingtest (#2)
- CLAUDE.md with collaboration rules and Planner/Generator/Evaluator cycle - .claude/ agents, commands, skills, hooks per Claude Code conventions - Sprint Contracts for sut-prober, normalizer, recorder, player, diff-reporter - SUT catalog (EG-BIM Modeler, 187 plugins) and .gitignore excluding SUT tree - PROGRESS.md / PLAN.md as shared agent handoff state - Solution scaffold targeting sut-prober PoC Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
53
.claude/skills/flaui-cookbook/SKILL.md
Normal file
53
.claude/skills/flaui-cookbook/SKILL.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
name: flaui-cookbook
|
||||
description: FlaUI and UI Automation recipes for the recordingtest project — waiting strategies, element finding patterns, pattern invocation, and integration with element-aware recording. Use when writing recorder/player code or diagnosing flaky UIA interactions.
|
||||
---
|
||||
|
||||
# FlaUI cookbook
|
||||
|
||||
## Dependencies
|
||||
- `FlaUI.Core`, `FlaUI.UIA3` (prefer UIA3 over UIA2)
|
||||
- Target: `net8.0-windows` or higher
|
||||
|
||||
## Launching the SUT
|
||||
|
||||
```csharp
|
||||
var app = FlaUI.Core.Application.Launch("EG-BIM Modeler/EG-BIM Modeler.exe");
|
||||
using var automation = new UIA3Automation();
|
||||
var main = app.GetMainWindow(automation, TimeSpan.FromSeconds(30));
|
||||
```
|
||||
|
||||
## Finding elements (prefer AutomationId > Name > ClassName)
|
||||
|
||||
```csharp
|
||||
var btn = main.FindFirstDescendant(cf => cf.ByAutomationId("BoxCommand")).AsButton();
|
||||
```
|
||||
|
||||
## Waiting — NEVER use fixed sleep
|
||||
|
||||
```csharp
|
||||
Retry.WhileNull(
|
||||
() => main.FindFirstDescendant(cf => cf.ByName("Ready")),
|
||||
timeout: TimeSpan.FromSeconds(10),
|
||||
interval: TimeSpan.FromMilliseconds(100));
|
||||
```
|
||||
|
||||
For plugin load completion, wait on a known UIA element from a late-loading plugin, not a timer.
|
||||
|
||||
## Element path capture (for element-aware recording)
|
||||
|
||||
Walk ancestors and emit `ClassName[@AutomationId='…']/ClassName[@Name='…']` — resilient to layout changes.
|
||||
|
||||
## 3D viewport fallback
|
||||
|
||||
SharpDX D3D11 surface is a UIA dead zone. Record:
|
||||
1. The hosting element's UIA path
|
||||
2. A normalized offset `(dx/width, dy/height)` inside that element
|
||||
3. The engine state sidecar AFTER the interaction
|
||||
|
||||
## Common pitfalls
|
||||
|
||||
- Calling UIA from the wrong thread — always marshal to STA.
|
||||
- Stale cached elements after modal dialogs — re-find after focus change.
|
||||
- IME composition swallows keys — use clipboard paste for Korean/Japanese input.
|
||||
- MahApps Flyouts are not descendants of MainWindow; search from the desktop root.
|
||||
37
.claude/skills/golden-file-normalizer/SKILL.md
Normal file
37
.claude/skills/golden-file-normalizer/SKILL.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
name: golden-file-normalizer
|
||||
description: Guidance and recipes for writing normalization rules that make SUT output files deterministic for golden-file regression testing. Use when designing or extending the normalizer module, or when diagnosing diff noise.
|
||||
---
|
||||
|
||||
# Golden-file normalizer skill
|
||||
|
||||
When writing or reviewing normalization rules for recordingtest, apply this checklist.
|
||||
|
||||
## Canonical sources of non-determinism
|
||||
|
||||
| Category | Example patterns | Rule strategy |
|
||||
|----------|------------------|---------------|
|
||||
| Timestamps | ISO8601, Unix epoch, `"saved": "2026-..."` | Replace with `<TS>` or strip key |
|
||||
| GUIDs / UUIDs | `xxxxxxxx-xxxx-...` | Replace with `<GUID-N>` (stable index per occurrence) |
|
||||
| Absolute paths | `C:\Users\...\`, `D:\MYCLAUDE_PROJECT\...` | Replace repo root with `<REPO>`, user with `<USER>` |
|
||||
| Recent files | `RecentFiles.json` | Empty the list or mask entirely |
|
||||
| Float precision | `3.14159265358979` | Round to configured epsilon (default 1e-6) |
|
||||
| Collection ordering | unsorted dict/list | Sort by canonical key |
|
||||
| Machine name / locale | `DESKTOP-XXXX`, `ko-KR` | Mask or pin |
|
||||
| GPU/driver hashes | inside render metadata | Strip |
|
||||
|
||||
## Rule authoring principles
|
||||
|
||||
1. **Rules are versioned** — bump the normalizer profile when adding/removing rules; scenarios pin a profile.
|
||||
2. **Never hide real bugs** — mask only fields proven non-deterministic across 3+ clean runs.
|
||||
3. **Text first** — parse JSON/XML semantically; use regex only as fallback.
|
||||
4. **Bidirectional tests** — every rule has a unit test with before/after samples.
|
||||
5. **Log what you normalized** — emit a sidecar `normalization.log` listing replacements for diagnostics.
|
||||
|
||||
## Output
|
||||
|
||||
When the user asks for a new rule, produce:
|
||||
- Rule name and profile membership
|
||||
- Regex or parser snippet (C#)
|
||||
- Unit test sample input/output
|
||||
- A note on which SUT file(s) it applies to
|
||||
Reference in New Issue
Block a user