import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:miler/views/helpers/constants/app_theme.dart'; import 'package:miler/views/introscreens/introscreen.dart'; /// The first-run slides. The illustrations are miniature mock-ups of the real /// Home screen rather than a centred Material icon, which means they are made of /// fixed-width rows — the hub rail on slide 1 is a dozen sized children in a /// single unflexed `Row`. That is exactly the shape that overflows on a narrow /// phone, so every slide is laid out at the narrowest screen the app supports. void main() { Future pump(WidgetTester tester, {required Size screen}) async { tester.view.physicalSize = Size(screen.width * 3, screen.height * 3); tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.resetPhysicalSize); addTearDown(tester.view.resetDevicePixelRatio); await tester.pumpWidget( ScreenUtilInit( designSize: const Size(390, 844), builder: (_, _) => MaterialApp( theme: AppTheme.light, home: const Introscreen(), ), ), ); await tester.pumpAndSettle(); } for (final size in const [ Size(320, 640), // smallest Android still in the fleet Size(360, 740), Size(390, 844), Size(430, 932), ]) { testWidgets('all three slides lay out at ${size.width.toInt()}pt', (tester) async { await pump(tester, screen: size); expect(tester.takeException(), isNull); // Slide 1 — the slot, its load, and the round trip. expect(find.text('Your route arrives ready'), findsOneWidget); expect(find.text('12:00 PM – 3:00 PM'), findsOneWidget); expect(find.text('Next'), findsOneWidget); // A near-full-width drag, so the page always snaps to the next one. A // velocity fling does not reliably cross the threshold here, because each // slide hosts its own vertical scroll view and the two share the arena. final swipe = Offset(-size.width * 0.9, 0); await tester.drag(find.byType(PageView), swipe); await tester.pumpAndSettle(); expect(tester.takeException(), isNull); expect(find.text('Work the stops in order'), findsOneWidget); expect(find.text('Skipped'), findsOneWidget); await tester.drag(find.byType(PageView), swipe); await tester.pumpAndSettle(); expect(tester.takeException(), isNull); expect(find.text('Collect, then close the loop'), findsOneWidget); expect(find.text('₹340 cash'), findsOneWidget); // Last slide swaps the CTA and drops Skip. expect(find.text('Get started'), findsOneWidget); expect(find.text('Skip'), findsNothing); }); } testWidgets('Skip is offered on the first slide', (tester) async { await pump(tester, screen: const Size(390, 844)); expect(find.text('Skip'), findsOneWidget); }); // The old copy pitched a gig marketplace — "pickups near you", accepted from a // feed. This product assigns routes from a hub. Onboarding that teaches the // wrong model is worse than none, so the wrong words are pinned out. testWidgets('does not promise a marketplace the app does not have', (tester) async { await pump(tester, screen: const Size(390, 844)); for (final wrong in [ 'Find pickups near you', 'Navigate the smart way', 'Earn more, every shift', 'Powered by AI', ]) { expect(find.text(wrong), findsNothing, reason: '"$wrong" is not this app'); } }); }