Adds a widget test asserting each destination icon keeps its Y position whether the rail is collapsed or expanded — a recurring regression. To drive expansion without a hover gesture (which trips RenderFlex overflow mid-transition), a test-only startSidebarExpanded flag threads StudioApp -> StudioShell -> _Sidebar (controller starts at 1.0, hover disabled); _SidebarItems get stable ValueKeys. analyze clean; new test and the existing smoke test pass. Signed-off-by: flemming-it <stefan.a.flemming@googlemail.com>
77 lines
2.6 KiB
Dart
77 lines
2.6 KiB
Dart
// Locks the sidebar invariant: destination icons sit at the same Y
|
|
// whether the rail is collapsed or expanded. The header rows above the
|
|
// destinations list have FIXED pixel heights (see _SidebarState), so
|
|
// expanding the rail (a width-only change) must not shift any
|
|
// destination vertically. This was a recurring regression source; this
|
|
// test pins it.
|
|
//
|
|
// Expansion is driven via StudioApp(startSidebarExpanded: true), NOT a
|
|
// hover gesture — hover mid-transition trips RenderFlex overflow in
|
|
// widget tests (see widget_test.dart). With the flag the rail's
|
|
// animation controller starts at value 1.0 (fully expanded), so no
|
|
// animation needs to settle.
|
|
|
|
import 'package:flutter/widgets.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:chain_studio/data/hub.dart';
|
|
import 'package:chain_studio/main.dart';
|
|
|
|
const _destinations = <String>[
|
|
'welcome',
|
|
'store',
|
|
'doctor',
|
|
'flows',
|
|
'audit',
|
|
'approvals',
|
|
'federation',
|
|
];
|
|
|
|
Map<String, double> _destinationYs(WidgetTester tester) {
|
|
final ys = <String, double>{};
|
|
for (final id in _destinations) {
|
|
final finder = find.byKey(ValueKey('sidebar-item-$id'));
|
|
expect(finder, findsOneWidget, reason: 'destination "$id" must render');
|
|
ys[id] = tester.getTopLeft(finder).dy;
|
|
}
|
|
return ys;
|
|
}
|
|
|
|
void main() {
|
|
testWidgets(
|
|
'sidebar destination Y positions are stable across rail expansion',
|
|
(tester) async {
|
|
// Collapsed (default).
|
|
await tester.pumpWidget(
|
|
const StudioApp(
|
|
initialThemeMode: ThemeModeValue.system,
|
|
initialLocale: Locale('en'),
|
|
),
|
|
);
|
|
// pump (not pumpAndSettle): the app has long-lived timers/animations
|
|
// that never "settle"; one frame is enough to lay the sidebar out.
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
final collapsed = _destinationYs(tester);
|
|
|
|
// Expanded: controller starts at 1.0 via the flag, hover disabled.
|
|
await tester.pumpWidget(
|
|
const StudioApp(
|
|
initialThemeMode: ThemeModeValue.system,
|
|
initialLocale: Locale('en'),
|
|
startSidebarExpanded: true,
|
|
),
|
|
);
|
|
await tester.pump(const Duration(milliseconds: 100));
|
|
final expanded = _destinationYs(tester);
|
|
|
|
for (final id in _destinations) {
|
|
expect(
|
|
expanded[id],
|
|
closeTo(collapsed[id]!, 0.5),
|
|
reason: 'destination "$id" Y shifted on expansion '
|
|
'(${collapsed[id]} -> ${expanded[id]}) — the rows above the '
|
|
'destinations list must keep fixed heights',
|
|
);
|
|
}
|
|
},
|
|
);
|
|
}
|