Files
oott/frontend/test/widget/navigation_transition_test.dart
T
rzuastiandClaude Opus 4.8 dedfe1c838 Fix ghosting in native screen transitions
Routed screens are transparent fragments rendered into the shell's single
Scaffold. A screen pushed on top (e.g. device detail) was therefore
see-through, leaving the screen beneath visible as it slid in, and the fade
page ignored secondaryAnimation so the covered screen sat frozen instead of
parallaxing out.

- Paint each routed page opaque (theme surface) so pushes cover cleanly.
- Drill into detail screens with a CupertinoPageTransition slide; the covered
  page parallaxes out via the same route animation, so both move in lockstep
  on the native iOS curve. Tabs keep their crossfade.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-07 18:29:57 -04:00

46 lines
1.7 KiB
Dart

import 'package:flutter_test/flutter_test.dart';
import 'package:frontend/navigation.dart';
import 'package:go_router/go_router.dart';
void main() {
// The app's real [router] is configured so that switching between top-level
// destinations crossfades (a [CustomTransitionPage]) instead of using the
// default platform slide, which would otherwise leave the outgoing screen
// visible behind the incoming one. Drilling into a detail screen uses its own
// custom page builder (an opaque iOS-style slide), not the default builder.
List<GoRoute> topLevelRoutes() {
final shell = router.configuration.routes.single as ShellRoute;
return shell.routes.cast<GoRoute>();
}
GoRoute routeByName(String name) =>
topLevelRoutes().firstWhere((r) => r.name == name);
group('navigation transitions', () {
test('top-level destinations use a page builder (crossfade)', () {
for (final name in ['home', 'devices', 'status', 'settings', 'about']) {
final route = routeByName(name);
expect(
route.pageBuilder,
isNotNull,
reason: '"$name" should crossfade via a custom page builder',
);
expect(route.builder, isNull, reason: '"$name" should not also build');
}
});
test('the device detail drill-in uses a custom page builder (slide)', () {
final devices = routeByName('devices');
final detail = devices.routes.single as GoRoute;
expect(detail.name, 'deviceDetail');
expect(
detail.pageBuilder,
isNotNull,
reason: 'the detail push should use the opaque drill-in slide page',
);
expect(detail.builder, isNull, reason: 'the detail should not also build');
});
});
}