ods-pages

ODS Regression Test Log

Running diagnostics as we build out TDD coverage across both frameworks.

Current Test Counts

Framework Test Files Test Cases Last Updated
React Web (unit + component + conformance) 55 1180+ Batches 1-6 + 2026-04-26 push
React Web (Playwright E2E) 13 51 (49 pass + 2 skip) Batch 8 + gap closure (2026-04-19)
Flutter Local (incl. widget, excl. @slow) 50+ 865 Batches 1-6 + 2026-04-26 push

Total: ~2096 tests across both frameworks. Widget tests (42) joined the gate 2026-04-26 — the multi-month “harness hang on Windows” was diagnosed as a FakeAsync vs sqflite_ffi interaction; fix lives in Frameworks/flutter-local/test/widget/_test_harness.dart (bootEngineFor + disposeAllFor + a runAsync-based pump loop).

Bugs Found by Regression Tests

# Bug Severity Found By Framework(s) Status
1 withData._id could overwrite target _id via FakeDataService Medium (security-adjacent) Batch 1 B2 React Fixed both frameworks
2 onEnd only fired on record actions, silently ignored elsewhere Medium Batch 2 B2-2 Both Fixed (Option B: universal onEnd)
3 hasAccess case-sensitive on required roles Low Batch 3 B3-1 Both Fixed
4 Cascade rename “old value” detection fragile Medium-High Batch 2 B2-1 Both Fixed (pre-query row)
5 Flutter cascade bailed when child DS missing Low Batch 2 B2-1 Flutter Fixed as part of #6
6 Flutter cascade shape differed from React Cross-framework contradiction Batch 2 B2-1 Flutter Flutter adopted React form
7 Flutter {_id} placeholder didn’t resolve Medium Batch 2 B2-3 Flutter Fixed
8 Flutter action chain didn’t catch thrown exceptions Medium Batch 2 B2-6 Flutter Fixed
9 Ternary evaluator broke on empty field substitution Medium Batch 6 B6-4 Both Fixed (\S* regex)
10 ActionHandler missing delete case (silent no-op) High (feature gap) Batch 6 B6-2 Flutter Fixed
11 Select field accepted values not in options[] Medium Batch 6 B6-1 Both Fixed (enum validation)
G1 Number field accepted non-numeric text Medium Batch 6 B6-1 Both Fixed
G3 Ternary only supported ==, not !=/>/< High (spec limitation) Batch 6 B6-4 Both Fixed (Option B: full operators)
G5 Template syntax mismatch (spec.md `` vs engine aggregates) Launch blocker (docs) Batch 6 B6-5 Both Fixed (updated spec.md)
G8 showMessage with empty message left lastMessage null Low Batch 6 B6-2 React Fixed
G9 Navigate to missing target silently succeeded Low Batch 6 B6-2 Both Fixed (logs warning)

Running total: 14 bugs/gaps found, 14 fixed

Design Decisions Made During Fixes

Decision Choice Rationale
onEnd semantics Universal (fires after any successful action) Matches spec author intuition
Template syntax (`` vs ${}) Text content uses literal text + aggregates only; ${} is for Quick Build templates Matches current engine behavior; less risk
Ternary operators Full set (==, !=, >, <, >=, <=) Pre-launch — adding later would be breaking
Nested ternaries Skipped (can achieve with computed fields) Parser complexity not worth it yet
NOW case-insensitivity Kept Harmless, backward compat
Template escape Skipped Low priority
_-prefix user field names Allowed Consistent across frameworks
Field name length cap None Consistent with React

Batch History

Batch 1 — Data flow & security fundamentals (✅)

8 scenarios × ~7 edge cases = 59 sub-tests per framework. Found: Bug #1. Fixed: Bug #1 (both frameworks).

Batch 2 — Action flow depth (✅)

7 scenarios × 4-6 edge cases = 31 sub-tests each. Found: Bugs #2, #4, #5, #6, #7, #8. Fixed: All.

Batch 3 — Auth & RBAC (✅)

6 scenarios × 5-10 edge cases. Found: Bug #3. Fixed: Bug #3.

Batch 4 — Edge cases (✅)

8 scenarios: empty DS, large DS, missing optionals, malformed JSON, unicode, concurrent, stale state, field name boundaries. Found: 0 bugs (both frameworks very robust).

Batch 5 — Component interactions (✅)

6 scenarios: form→list sync, recordSource nav, toggle, kanban, aggregates, expression evaluation. Found: 0 bugs (both frameworks).

Batch 6 — Spec completeness (✅)

5 scenarios: every field type, every action type, formula evaluator, expression evaluator, template engine. Found: Bugs #9, #10, #11, G1, G3, G5, G8, G9. Fixed: All.

What’s Next

The regression suite has found and fixed 14 issues across 6 batches. Potential future work:

Batch 7 — Flutter widget tests (in gate as of 2026-04-26)

42 widget tests covering button, chart, detail, form, kanban, list, page renderer, summary, tabs, text. Files live in Frameworks/flutter-local/test/widget/.

Status: All 42 in the local + CI gate. Earlier diagnosis blamed “flutter_tools temp-dir race”; the actual root cause was flutter_test’s FakeAsync zone intercepting (but never firing) the native-bridge timers sqflite_ffi schedules — so pumpAndSettle waited forever for “settle.” Fix: setup runs inside tester.runAsync to escape the FakeAsync zone (bootEngineFor / disposeAllFor), and the harness’s pumpAndSettle does fixed real-time pump rounds (16 × 100ms) instead of FakeAsync settling. Plus a pumpUntilFound helper for cases where fixed timing isn’t enough. Diagnosis + harness rewrite + 7 stale-test fixes (SingleChildScrollView wrapping a ListView, headers asserted on empty data sources, form not in pages map) all landed 2026-04-26.

Batch 10 — Conformance parity (continuous since 2026-04-19)

Cross-framework parity contract via the ODS conformance driver contract (ADR-0001). Shared specs live in Frameworks/conformance/specs/; the TS scenario list at Frameworks/conformance/src/scenarios.ts mirrors the Dart side at Frameworks/flutter-local/test/conformance/scenarios.dart.

Status (2026-04-26): 26 scenarios × 2 drivers = 52 parity tests. Both drivers green on every commit (gated by publish.sh + the flutter/react GH workflows).

Capabilities exercised: core, action:submit, action:update, action:delete, action:navigate, action:showMessage, action:recordNav, auth:multiUser, auth:selfRegistration, auth:ownership, formulas, summary, tabs, chart, kanban, detail, cascadeRename, theme, rowActions.

Bugs / parity gaps surfaced and fixed by this contract:

Open parity gaps: recordSource default-order parity (s23) — PocketBase defaults to created desc; SQLite returns insertion order. s23 sidesteps this with order-agnostic assertions. Real fix (optional sort directive on firstRecord) tracked in TODO.md.

Workflow: the conformance suite is now treated as the contract, not coverage applied after the fact. Cross-framework changes go in red on both drivers, then green on both — see CONTRIBUTING.md → Conformance scenarios — contract-first.

Batch 8 — E2E browser tests (implemented 2026-04-19)

Expanded Playwright coverage from the 3-smoke starter to 22 regression tests (21 passing, 1 skipped) across 5 new spec files, plus the 5 critical + 3 smoke specs already in place. Full run is 47 passed, 3 skipped in ~1.6 min on a single worker (serial, one shared PB instance).

Infrastructure added (Frameworks/react-web/tests/e2e/):

New specs in tests/e2e/regression/:

Related product-code changes:

Gap closure (same-day follow-up):

Post-closure totals: 49 passing + 2 skipped in ~1.3 min. Unit suite untouched (1117 passing).

Batch 9 — Performance tests (implemented, 5 flaky on slow Windows)

Frameworks/flutter-local/test/integration/batch9_performance_test.dart covers parse speed, data-service throughput (insert/query/filter), action chain speed, engine reactivity.

Status on Windows/c:\Apps: P1 parsing, P3 spec loading, P5 reactivity all pass. P2 data-service (insert/query/filter 10k rows) and P4 action chains (100 sequential submits) occasionally exceed their generous budgets on this dev machine’s slow I/O. 794/800 integration+engine tests pass; the 5 flaky P2/P4 cases are timing-only, not correctness regressions.


2026-04-19 — Off-OneDrive move + architecture cleanup (not a numbered batch)

Not test work, but the moves that followed the project migration to c:\Apps\One-does-simply: