import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:flutter_screenutil/flutter_screenutil.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:miler/views/Dashboard/activity/activity_page.dart'; import 'package:miler/views/Dashboard/home/homepage.dart'; import 'package:miler/views/Dashboard/profile/Profilepage.dart'; import 'package:miler/views/helpers/constants/Colorconstants.dart'; /// ── A day's work is a list, not a stack of cards ── /// /// Every finished stop was a filled, rounded card with 12pt of air under it, /// and inside each one a *second*, white panel holding the three figures. So the /// page came down the screen as grey slabs with white slabs punched into them — /// the card-inside-card shape, repeated once per stop — and on top of that every /// row opened with a 40pt green disc that was identical on all of them. /// /// Finished stops are all the same kind of thing, arriving in one order, read by /// scanning down. That is a list, and a list is separated by rules. void main() { String day(DateTime t) => '${t.year}-${t.month.toString().padLeft(2, '0')}-' '${t.day.toString().padLeft(2, '0')}'; Map finished( String id, String name, String address, { required String type, double cash = 0, int minsAgo = 30, }) { final now = DateTime.now(); final at = now.subtract(Duration(minutes: minsAgo)); return { 'orderid': id, 'type': type, 'pickupcustomer': name, 'pickupaddress': address, 'orderstatus': 'picked', 'completedday': day(now), 'completedat': at.toIso8601String(), 'startedat': at.subtract(const Duration(minutes: 14)).toIso8601String(), if (cash > 0) 'collectionamt': '$cash', 'proof': {if (cash > 0) 'amountcollected': cash}, }; } Future pumpActivity(WidgetTester tester) async { SharedPreferences.setMockInitialValues({ 'userId': 1, 'completed_bookings': jsonEncode([ finished( 'DM240817', 'Sundar Textiles', '78, Cross Cut Road, Gandhipuram, Coimbatore', type: 'combined', cash: 2450, minsAgo: 22, ), finished( 'DM240816', 'Green Leaf Grocers', '29, Kovaipudur Main Road, Coimbatore', type: 'delivery', minsAgo: 68, ), ]), }); tester.view.physicalSize = const Size(390 * 3, 844 * 3); tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.reset); await tester.pumpWidget( ScreenUtilInit( designSize: const Size(390, 844), builder: (_, _) => const MaterialApp(home: ActivityPage()), ), ); await tester.pumpAndSettle(const Duration(seconds: 2)); } testWidgets('a finished stop is not a card', (tester) async { await pumpActivity(tester); expect(find.text('Sundar Textiles'), findsOneWidget); // `cardSurface` was the row fill and `pureSurface` the fill of the figure // panel nested inside it. Neither may come back: on a white page a filled // row is a box round a list item, and a filled panel inside a filled row is // the shape this page was rebuilt to remove. final fills = tester .widgetList(find.byType(Container)) .map((c) => c.decoration) .whereType() .map((d) => d.color) .toList(); expect(fills, isNot(contains(ColorConstants.cardSurface))); }); testWidgets('the figures line up across rows, not just within one', ( tester, ) async { await pumpActivity(tester); // The point of three fixed columns is comparing one stop against the next. // While every row sat in its own padded card that only held *inside* a row; // sharing the page margin is what makes column two of one stop sit directly // above column two of the one below. final captions = tester.widgetList(find.text('COLLECTED')).toList(); expect(captions.length, 2); final rects = [ for (var i = 0; i < 2; i++) tester.getRect(find.text('COLLECTED').at(i)), ]; expect(rects[0].left, closeTo(rects[1].left, 0.5)); // Column one starts flush with the stop name above it — no card inset. final time = tester.getRect(find.text('TIME').first); final name = tester.getRect(find.text('Sundar Textiles')); expect(time.left, closeTo(name.left, 0.5)); }); testWidgets('the stop type is a dotted word, not a filled tag', ( tester, ) async { await pumpActivity(tester); // Two tinted rectangles under every address — the type and the order id — // were the loudest things on a row whose subject is the figures below them. expect(find.text('Pickup & Delivery'), findsOneWidget); // `P&D` is `chipLabel`, which only ever reached this page through the // filled tag. (`badgeLabel` still appears inside the collapsed detail, // which `AnimatedCrossFade` builds either way — that one is a field value, // not a mark.) expect(find.text('P&D'), findsNothing); final label = tester.widget(find.text('Pickup & Delivery')); expect(label.style!.color, ColorConstants.combinedAccent); // The reference stays copyable, in grey, without claiming any rank. final id = tester.widget(find.text('#DM240817')); expect(id.style!.color, ColorConstants.secondaryText); }); testWidgets('column captions are readable, not disabled-grey', ( tester, ) async { await pumpActivity(tester); // #C7C7CC is a disabled-control colour. It measured about 1.9:1 on the // white page, which made the three words naming the columns the least // readable text on a screen used outdoors. for (final caption in const ['TIME', 'RIDDEN', 'COLLECTED']) { final text = tester.widget(find.text(caption).first); expect(text.style!.color, ColorConstants.secondaryText); expect(text.style!.color, isNot(ColorConstants.disabledFill)); } }); testWidgets('the four tabs agree on what colour the paper is', ( tester, ) async { // Account was on `surface` (#FCF9F8, a warm off-white) while Home and // Activity were on `pureSurface`. Bookings hides its background under // cards; Account is bare rows, so the whole tab read a shade dirtier. Color? bgOf(Widget page) { final scaffolds = []; void visit(Element e) { final w = e.widget; if (w is Scaffold) scaffolds.add(w); e.visitChildren(visit); } WidgetsBinding.instance.rootElement!.visitChildren(visit); return scaffolds.isEmpty ? null : scaffolds.first.backgroundColor; } SharedPreferences.setMockInitialValues({'userId': 1}); tester.view.physicalSize = const Size(390 * 3, 844 * 3); tester.view.devicePixelRatio = 3.0; addTearDown(tester.view.reset); for (final page in [const ActivityPage(), const ProfilePage()]) { await tester.pumpWidget( ScreenUtilInit( designSize: const Size(390, 844), builder: (_, _) => MaterialApp(home: page), ), ); await tester.pump(); expect(bgOf(page), ColorConstants.pureSurface); } }); }