Initial commit
This commit is contained in:
88
test/flow_test.dart
Normal file
88
test/flow_test.dart
Normal file
@@ -0,0 +1,88 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:doormile/main.dart';
|
||||
|
||||
/// Drives the app through its main flows at a phone-sized viewport to catch
|
||||
/// layout overflows and runtime exceptions on each screen.
|
||||
void main() {
|
||||
testWidgets('full user journey renders without errors', (WidgetTester tester) async {
|
||||
tester.view.physicalSize = const Size(1170, 2532); // iPhone-ish @3x
|
||||
tester.view.devicePixelRatio = 3.0;
|
||||
addTearDown(tester.view.reset);
|
||||
|
||||
await tester.pumpWidget(const DoormileApp());
|
||||
|
||||
// Splash -> Onboarding
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Send a parcel in one touch'), findsOneWidget);
|
||||
|
||||
// Skip onboarding -> Login
|
||||
await tester.tap(find.text('Skip'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Welcome back'), findsOneWidget);
|
||||
|
||||
// Enter phone and request OTP
|
||||
await tester.enterText(find.byType(TextField).first, '9876543210');
|
||||
await tester.pump();
|
||||
await tester.tap(find.text('Send OTP'));
|
||||
await tester.pump(const Duration(milliseconds: 1400));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Verify your number'), findsOneWidget);
|
||||
|
||||
// Fill the 6 OTP boxes
|
||||
final otpBoxes = find.byType(TextField);
|
||||
for (int i = 0; i < 6; i++) {
|
||||
await tester.enterText(otpBoxes.at(i), '1');
|
||||
await tester.pump();
|
||||
}
|
||||
await tester.tap(find.text('Verify & Continue'));
|
||||
await tester.pump(const Duration(milliseconds: 1300));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
// Home
|
||||
expect(find.text('Send a parcel'), findsOneWidget);
|
||||
|
||||
// Start a booking
|
||||
await tester.tap(find.text('Book Now'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Step 1: Confirm Pickup'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Continue'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('What are you sending?'), findsOneWidget);
|
||||
|
||||
await tester.tap(find.text('Continue'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('CHOOSE SERVICE'), findsOneWidget);
|
||||
|
||||
// Confirm & Continue -> review
|
||||
await tester.tap(find.textContaining('Confirm & Continue'));
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Review Booking'), findsWidgets);
|
||||
|
||||
// Pop all the way back to the home shell.
|
||||
for (int i = 0; i < 4; i++) {
|
||||
if (find.text('Send a parcel').evaluate().isNotEmpty) break;
|
||||
await tester.pageBack();
|
||||
await tester.pumpAndSettle();
|
||||
}
|
||||
expect(find.text('Send a parcel'), findsOneWidget);
|
||||
|
||||
// Wallet tab
|
||||
await tester.tap(find.text('Wallet').first);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Doormile Wallet'), findsOneWidget);
|
||||
|
||||
// Profile tab
|
||||
await tester.tap(find.text('Profile').first);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('Riya Sharma'), findsOneWidget);
|
||||
|
||||
// Track tab (orders list)
|
||||
await tester.tap(find.text('Track').first);
|
||||
await tester.pumpAndSettle();
|
||||
expect(find.text('My Parcels'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
73
test/screens_test.dart
Normal file
73
test/screens_test.dart
Normal file
@@ -0,0 +1,73 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
|
||||
import 'package:doormile/state/app_state.dart';
|
||||
import 'package:doormile/theme/app_theme.dart';
|
||||
import 'package:doormile/screens/onboarding_screen.dart';
|
||||
import 'package:doormile/screens/login_screen.dart';
|
||||
import 'package:doormile/screens/otp_screen.dart';
|
||||
import 'package:doormile/screens/main_shell.dart';
|
||||
import 'package:doormile/screens/home_screen.dart';
|
||||
import 'package:doormile/screens/wallet_screen.dart';
|
||||
import 'package:doormile/screens/profile_screen.dart';
|
||||
import 'package:doormile/screens/help_support_screen.dart';
|
||||
import 'package:doormile/screens/booking/booking_pickup_screen.dart';
|
||||
import 'package:doormile/screens/booking/parcel_details_screen.dart';
|
||||
import 'package:doormile/screens/booking/service_price_screen.dart';
|
||||
import 'package:doormile/screens/booking/booking_preview_screen.dart';
|
||||
import 'package:doormile/screens/booking/booking_success_screen.dart';
|
||||
import 'package:doormile/screens/tracking/my_orders_screen.dart';
|
||||
import 'package:doormile/screens/tracking/live_tracking_screen.dart';
|
||||
import 'package:doormile/screens/tracking/shipment_journey_screen.dart';
|
||||
|
||||
/// Renders each screen in isolation at a phone viewport and settles it, so the
|
||||
/// test framework flags any overflow in the *settled* layout (no transition
|
||||
/// transients). A pumped order is placed first so success/tracking have data.
|
||||
Future<void> _renderScreen(WidgetTester tester, Widget child) async {
|
||||
final state = AppState()
|
||||
..login()
|
||||
..setPhone('98765 43210');
|
||||
state.placeOrder();
|
||||
await tester.pumpWidget(
|
||||
ChangeNotifierProvider<AppState>.value(
|
||||
value: state,
|
||||
child: MaterialApp(theme: AppTheme.light, home: child),
|
||||
),
|
||||
);
|
||||
await tester.pump(const Duration(milliseconds: 400));
|
||||
await tester.pump(const Duration(milliseconds: 400));
|
||||
}
|
||||
|
||||
void main() {
|
||||
setUp(() {});
|
||||
|
||||
final screens = <String, Widget Function()>{
|
||||
'Onboarding': () => const OnboardingScreen(),
|
||||
'Login': () => const LoginScreen(),
|
||||
'OTP': () => const OtpScreen(),
|
||||
'MainShell/Home': () => const MainShell(),
|
||||
'Home': () => const Scaffold(body: HomeScreen()),
|
||||
'Wallet': () => const Scaffold(body: WalletScreen()),
|
||||
'Profile': () => const Scaffold(body: ProfileScreen()),
|
||||
'Help': () => const HelpSupportScreen(),
|
||||
'BookingPickup': () => const BookingPickupScreen(),
|
||||
'ParcelDetails': () => const ParcelDetailsScreen(),
|
||||
'ServicePrice': () => const ServicePriceScreen(),
|
||||
'BookingPreview': () => const BookingPreviewScreen(),
|
||||
'BookingSuccess': () => const BookingSuccessScreen(),
|
||||
'MyOrders': () => const MyOrdersScreen(),
|
||||
'LiveTracking': () => const LiveTrackingScreen(),
|
||||
'ShipmentJourney': () => const ShipmentJourneyScreen(),
|
||||
};
|
||||
|
||||
for (final entry in screens.entries) {
|
||||
testWidgets('${entry.key} renders cleanly at phone size', (tester) async {
|
||||
tester.view.physicalSize = const Size(1170, 2532);
|
||||
tester.view.devicePixelRatio = 3.0;
|
||||
addTearDown(tester.view.reset);
|
||||
await _renderScreen(tester, entry.value());
|
||||
expect(tester.takeException(), isNull);
|
||||
});
|
||||
}
|
||||
}
|
||||
19
test/widget_test.dart
Normal file
19
test/widget_test.dart
Normal file
@@ -0,0 +1,19 @@
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:doormile/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('App boots and advances from splash to onboarding',
|
||||
(WidgetTester tester) async {
|
||||
await tester.pumpWidget(const DoormileApp());
|
||||
|
||||
// Splash shows the brand wordmark.
|
||||
expect(find.text('Doormile'), findsWidgets);
|
||||
|
||||
// Let the splash auto-navigation timer fire, then settle on onboarding.
|
||||
await tester.pump(const Duration(seconds: 3));
|
||||
await tester.pumpAndSettle();
|
||||
|
||||
expect(find.text('Send a parcel in one touch'), findsOneWidget);
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user