101 lines
3.3 KiB
Dart
101 lines
3.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:krow_worker_app/core/theme.dart';
|
|
import 'package:krow_worker_app/screens/clock_screen.dart';
|
|
import 'package:krow_worker_app/screens/pay_screens.dart';
|
|
import 'package:krow_worker_app/screens/profile_screen.dart';
|
|
import 'package:krow_worker_app/screens/shifts_screen.dart';
|
|
import 'package:krow_worker_app/screens/today_screen.dart';
|
|
import 'package:krow_worker_app/state/session_controller.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
/// Overflow is reported as a thrown FlutterError, and the stripes only appear
|
|
/// in a debug build — so a release web check cannot see it and it reaches a
|
|
/// device first. These pump every tab at real phone sizes to catch it here.
|
|
void main() {
|
|
late SharedPreferences prefs;
|
|
|
|
setUp(() async {
|
|
SharedPreferences.setMockInitialValues({});
|
|
prefs = await SharedPreferences.getInstance();
|
|
});
|
|
|
|
Future<void> pumpScreen(
|
|
WidgetTester tester,
|
|
Widget screen, {
|
|
required Size size,
|
|
double textScale = 1.0,
|
|
}) async {
|
|
tester.view.physicalSize = size;
|
|
tester.view.devicePixelRatio = 1.0;
|
|
addTearDown(tester.view.reset);
|
|
|
|
// Captured rather than left to the default handler, so a failure names the
|
|
// widget that overflowed instead of just the pixel count.
|
|
final errors = <FlutterErrorDetails>[];
|
|
final previousHandler = FlutterError.onError;
|
|
FlutterError.onError = errors.add;
|
|
|
|
await tester.pumpWidget(
|
|
ProviderScope(
|
|
overrides: [prefsProvider.overrideWithValue(prefs)],
|
|
child: MaterialApp(
|
|
theme: buildKrowTheme(),
|
|
home: MediaQuery(
|
|
data: MediaQueryData(
|
|
size: size,
|
|
textScaler: TextScaler.linear(textScale),
|
|
// A notch, so the header has to make room for it.
|
|
padding: const EdgeInsets.only(top: 44, bottom: 34),
|
|
),
|
|
child: screen,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
await tester.pump();
|
|
FlutterError.onError = previousHandler;
|
|
|
|
if (errors.isNotEmpty) {
|
|
fail(errors.map((e) => e.toString()).join('\n\n'));
|
|
}
|
|
|
|
// Screens with running timers must be torn down, or the test fails on a
|
|
// pending timer rather than on what it is checking.
|
|
await tester.pumpWidget(const SizedBox.shrink());
|
|
}
|
|
|
|
final screens = <String, Widget>{
|
|
'Today': const TodayScreen(),
|
|
'Shifts': const ShiftsScreen(),
|
|
'Clock': const ClockScreen(),
|
|
'Pay': const PayScreen(),
|
|
'Profile': const ProfileScreen(),
|
|
};
|
|
|
|
// A small phone, a tall one, and a short-but-wide one.
|
|
final sizes = <String, Size>{
|
|
'small phone': const Size(360, 640),
|
|
'tall phone': const Size(412, 915),
|
|
'compact': const Size(320, 568),
|
|
};
|
|
|
|
for (final screen in screens.entries) {
|
|
for (final size in sizes.entries) {
|
|
testWidgets('${screen.key} lays out on a ${size.key}', (tester) async {
|
|
await pumpScreen(tester, screen.value, size: size.value);
|
|
});
|
|
}
|
|
|
|
testWidgets('${screen.key} survives large system text', (tester) async {
|
|
await pumpScreen(
|
|
tester,
|
|
screen.value,
|
|
size: const Size(360, 640),
|
|
textScale: 1.3,
|
|
);
|
|
});
|
|
}
|
|
}
|