move docs to docs/ folder, merge architecture files, update references
This commit is contained in:
60
docs/TESTING-FRAMEWORK.md
Normal file
60
docs/TESTING-FRAMEWORK.md
Normal file
@@ -0,0 +1,60 @@
|
||||
# Automated Testing Framework
|
||||
|
||||
The designer-test (`designer-test/`) provides automated UI testing.
|
||||
|
||||
## Test Architecture
|
||||
|
||||
1. **WindowController**: Finds designer window, sends mouse/keyboard events via Windows SendInput API
|
||||
2. **HierarchyReader**: Parses UI hierarchy JSON to find elements by ID/class (with retry logic and exponential backoff)
|
||||
3. **LogParser**: Monitors log file for navigation events
|
||||
4. **TestRunner**: Orchestrates test execution, reports results
|
||||
5. **UIInspector**: Dumps UI hierarchy with atomic writes (temp file + rename pattern)
|
||||
|
||||
## Key Implementation Details
|
||||
|
||||
- **Path Normalization**: RmlUi uses `|` instead of `:` in Windows paths (e.g., `D|\Dev\...`). The UIInspector normalizes paths for correct document matching.
|
||||
- **Atomic File Writes**: Hierarchy files are written to `.tmp` then renamed to prevent partial reads.
|
||||
- **Retry with Backoff**: HierarchyReader retries up to 10 times with exponential backoff (30ms base) and validates JSON completeness.
|
||||
- **Dynamic Back Button**: `GoHome()` finds back buttons from hierarchy by class (`app-bar-nav` or `browser-nav-btn`) instead of fixed coordinates.
|
||||
|
||||
## Writing Tests
|
||||
|
||||
```cpp
|
||||
// Find element by ID and click it
|
||||
bool ClickById(TestContext& ctx, const std::string& id) {
|
||||
ctx.hierarchy.Reload();
|
||||
auto element = ctx.hierarchy.FindById(id);
|
||||
if (!element) return false;
|
||||
|
||||
int x = element->bounds.centerX();
|
||||
int y = element->bounds.centerY();
|
||||
ScaleToPhysical(ctx, x, y); // Convert logical to physical coords
|
||||
ctx.window.SendClick(x, y);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Test example
|
||||
bool TestNavigateToDialer(TestContext& ctx) {
|
||||
GoHome(ctx);
|
||||
ctx.log.Clear();
|
||||
|
||||
if (!ClickById(ctx, "dock-phone")) return false;
|
||||
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||
ctx.log.Reload();
|
||||
return ctx.log.Contains("Loaded screen: apps/dialer/dialer.rml");
|
||||
}
|
||||
```
|
||||
|
||||
## Test Output
|
||||
|
||||
Tests produce JSON results at `test_results.json`:
|
||||
```json
|
||||
{
|
||||
"name": "Mosis Designer UI Tests",
|
||||
"summary": {"passed": 5, "failed": 0, "total": 5},
|
||||
"tests": [
|
||||
{"name": "Navigate to Dialer", "status": "passed", "duration_ms": 3500}
|
||||
]
|
||||
}
|
||||
```
|
||||
Reference in New Issue
Block a user