import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:fuel_tax_tracker/widgets/onboarding_tour_overlay.dart'; /// Unit-level coverage of the tour's presentational overlay widget, /// independent of MainShell's step-sequencing/navigation logic (covered /// in main_shell_test.dart's onboarding-tour group instead). void main() { Widget wrap(Widget child) => MaterialApp(home: Scaffold(body: child)); testWidgets('shows the title, description, and step count', (tester) async { final targetKey = GlobalKey(); await tester.pumpWidget(wrap( OnboardingTourOverlay( targetKey: targetKey, title: 'Example Title', description: 'Example description text.', stepNumber: 2, totalSteps: 4, onNext: () {}, onSkip: () {}, ), )); expect(find.text('Example Title'), findsOneWidget); expect(find.text('Example description text.'), findsOneWidget); expect(find.text('Step 2 of 4'), findsOneWidget); }); testWidgets('shows "Next" before the last step and "Got It" on the last step', (tester) async { final targetKey = GlobalKey(); await tester.pumpWidget(wrap( OnboardingTourOverlay( targetKey: targetKey, title: 'T', description: 'D', stepNumber: 1, totalSteps: 3, onNext: () {}, onSkip: () {}, ), )); expect(find.widgetWithText(FilledButton, 'Next'), findsOneWidget); expect(find.widgetWithText(FilledButton, 'Got It'), findsNothing); await tester.pumpWidget(wrap( OnboardingTourOverlay( targetKey: targetKey, title: 'T', description: 'D', stepNumber: 3, totalSteps: 3, onNext: () {}, onSkip: () {}, ), )); expect(find.widgetWithText(FilledButton, 'Got It'), findsOneWidget); expect(find.widgetWithText(FilledButton, 'Next'), findsNothing); }); testWidgets('invokes onNext/onSkip when their buttons are tapped', (tester) async { var nextTapped = false; var skipTapped = false; final targetKey = GlobalKey(); await tester.pumpWidget(wrap( OnboardingTourOverlay( targetKey: targetKey, title: 'T', description: 'D', stepNumber: 1, totalSteps: 2, onNext: () => nextTapped = true, onSkip: () => skipTapped = true, ), )); await tester.tap(find.widgetWithText(TextButton, 'Skip Tour')); expect(skipTapped, isTrue); await tester.tap(find.widgetWithText(FilledButton, 'Next')); expect(nextTapped, isTrue); }); testWidgets( 'renders without crashing when the target key has no RenderObject yet — falls back to a ' 'centered card', (tester) async { final targetKey = GlobalKey(); // never attached to anything await tester.pumpWidget(wrap( OnboardingTourOverlay( targetKey: targetKey, title: 'T', description: 'D', stepNumber: 1, totalSteps: 1, onNext: () {}, onSkip: () {}, ), )); expect(find.text('T'), findsOneWidget); }); testWidgets('tapping the dimmed barrier does not invoke onNext or onSkip', (tester) async { var nextTapped = false; var skipTapped = false; final targetKey = GlobalKey(); await tester.pumpWidget(wrap( OnboardingTourOverlay( targetKey: targetKey, title: 'T', description: 'D', stepNumber: 1, totalSteps: 1, onNext: () => nextTapped = true, onSkip: () => skipTapped = true, ), )); // Top-left corner — away from the card, which sits mid/lower-screen. await tester.tapAt(const Offset(5, 5)); await tester.pump(); expect(nextTapped, isFalse); expect(skipTapped, isFalse); }); }