import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:doormile_cx/main.dart'; import 'package:doormile_cx/ui/screens/booking/booking_routes.dart'; /// ───────────────────────────────────────────────────────────────────────── /// WHICH WAY A PAGE LEAVES /// /// The app's pages used to arrive from the right and leave to the right, which /// is the direction the system back gesture drags — a page that slides off /// sideways under a button press reads as a swipe the customer did not make. /// /// They now rise from the bottom and fall back down it. A golden cannot see /// motion, so this is where that direction is held: mid-push the incoming page /// is *below* where it lands and exactly on its horizontal mark, and mid-pop it /// is on its way back down rather than off to one side. /// ───────────────────────────────────────────────────────────────────────── void main() { const key = ValueKey('pushed-page'); Future pumpApp(WidgetTester tester) async { await tester.pumpWidget( MaterialApp( theme: buildDoormileTheme(), home: Builder( builder: (context) => Scaffold( body: Center( child: TextButton( onPressed: () => Navigator.of(context).push( bookingRoute( 'x', (_) => const Scaffold( key: key, body: Center(child: Text('second')), ), ), ), child: const Text('go'), ), ), ), ), ), ); } /// Where the pushed page's top-left corner currently sits. Offset cornerOf(WidgetTester tester) => tester.getTopLeft(find.byKey(key).first); testWidgets('a push arrives from below, not from the side', (tester) async { await pumpApp(tester); final screen = tester.view.physicalSize / tester.view.devicePixelRatio; await tester.tap(find.text('go')); await tester.pump(); // Partway through the 420ms push. await tester.pump(const Duration(milliseconds: 120)); final corner = cornerOf(tester); expect( corner.dy, greaterThan(0), reason: 'the arriving page should still be below its resting place', ); expect( corner.dy, lessThan(screen.height), reason: 'and already on screen, not still parked off the bottom', ); expect( corner.dx, 0, reason: 'nothing travels horizontally any more', ); await tester.pumpAndSettle(); expect(cornerOf(tester), Offset.zero); }); testWidgets('back drops the page down the screen', (tester) async { await pumpApp(tester); await tester.tap(find.text('go')); await tester.pumpAndSettle(); final settled = cornerOf(tester); expect(settled, Offset.zero); // The back button, not a gesture. final popped = tester.state(find.byType(Navigator)); popped.pop(); await tester.pump(); await tester.pump(const Duration(milliseconds: 120)); final leaving = cornerOf(tester); expect( leaving.dy, greaterThan(0), reason: 'the page being left should be heading down, not up', ); expect( leaving.dx, 0, reason: 'and not sideways, which is what it used to do', ); }); testWidgets('it travels the whole height, so the direction is readable', ( tester, ) async { await pumpApp(tester); final screen = tester.view.physicalSize / tester.view.devicePixelRatio; await tester.tap(find.text('go')); await tester.pump(); // One frame in: the page has barely moved, so it is still near the bottom // edge. A 14%-of-the-width nudge — what this replaced — would put it within // a few points of its resting place by now. await tester.pump(const Duration(milliseconds: 16)); expect( cornerOf(tester).dy, greaterThan(screen.height * 0.5), reason: 'a token nudge has no direction a customer can name', ); }); testWidgets('going back is quicker than going forward', (tester) async { final route = bookingRoute('x', (_) => const SizedBox()) as DmPageRoute; expect(route.transitionDuration, const Duration(milliseconds: 420)); expect(route.reverseTransitionDuration, const Duration(milliseconds: 340)); expect( route.reverseTransitionDuration < route.transitionDuration, isTrue, reason: 'the customer already knows what is behind them', ); }); }