material_adaptive_sheets/test/screenshots_test.dart
2026-11-03 14:51:33 -05:00

176 lines
5.1 KiB
Dart

import "dart:io";
import "package:flutter/services.dart";
import "package:flutter_test/flutter_test.dart";
import "package:material_adaptive_sheets/material_adaptive_sheets.dart";
import "package:material_ui/material_ui.dart";
// Renders the README screenshots into assets/screenshots.
// Regenerate them with `flutter test --update-goldens`.
const mobile = Size(400, 720);
const desktop = Size(900, 600);
Future<void> loadFonts() async {
final fonts =
"${Platform.environment["FLUTTER_ROOT"]}/bin/cache/artifacts/material_fonts";
Future<void> load(String family, List<String> files) async {
final loader = FontLoader(family);
for (final file in files) {
loader.addFont(
File("$fonts/$file")
.readAsBytes()
.then((bytes) => ByteData.sublistView(bytes)),
);
}
await loader.load();
}
await load("Roboto", [
"Roboto-Regular.ttf",
"Roboto-Medium.ttf",
"Roboto-Bold.ttf",
]);
await load("MaterialIcons", ["MaterialIcons-Regular.otf"]);
}
class const Demo({super.key}) extends StatelessWidget {
@override
Widget build(BuildContext context) => Scaffold(
appBar: AppBar(
title: const Text("Inbox"),
actions: [
Builder(
builder: (context) => IconButton(
key: const Key("popover"),
icon: const Icon(Icons.info_outline),
tooltip: "Details",
onPressed: () => context.showAdaptivePopover(
(context) => const Padding(
padding: .all(16),
child: Column(
mainAxisSize: .min,
crossAxisAlignment: .start,
spacing: 8,
children: [
Text(
"Inbox",
style: TextStyle(fontSize: 18, fontWeight: .w500),
),
Text("3 conversations, 1 unread"),
Text("Last synced just now"),
],
),
),
),
),
),
AdaptiveMenuButton<String>(
key: const Key("menu"),
icon: const Icon(Icons.more_vert),
tooltip: "More",
itemBuilder: (context) => const [
PopupMenuItem(
value: "read",
child: ListTile(
leading: Icon(Icons.done_all),
title: Text("Mark all as read"),
),
),
PopupMenuItem(
value: "archive",
child: ListTile(
leading: Icon(Icons.archive_outlined),
title: Text("Archive"),
),
),
PopupMenuItem(
value: "settings",
child: ListTile(
leading: Icon(Icons.settings_outlined),
title: Text("Settings"),
),
),
],
),
],
),
body: ListView(
children: [
for (final (name, message) in const [
("Alice", "Are we still on for tomorrow?"),
("Bob", "Sent you the photos from the trip"),
("Carol", "Thanks for the help!"),
])
ListTile(
leading: CircleAvatar(child: Text(name[0])),
title: Text(name),
subtitle: Text(message),
),
],
),
floatingActionButton: Builder(
builder: (context) => FloatingActionButton(
key: const Key("sheet"),
tooltip: "Delete",
child: const Icon(Icons.delete_outline),
onPressed: () => context.showAdaptiveSheet(
(context) => SheetLayout(
title: const Text("Delete conversations?"),
actions: [
TextButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text("Cancel"),
),
FilledButton(
onPressed: () => Navigator.of(context).pop(),
child: const Text("Delete"),
),
],
children: const [
Text(
"All 3 conversations in your inbox will be deleted. This can't be undone.",
),
],
),
),
),
),
);
}
void main() {
setUpAll(loadFonts);
for (final (name, size) in const [("mobile", mobile), ("desktop", desktop)]) {
for (final surface in const ["sheet", "menu", "popover"]) {
testWidgets("$surface on $name", (tester) async {
tester.view
..physicalSize = size * 2
..devicePixelRatio = 2;
addTearDown(tester.view.reset);
// Draw real shadows instead of the outlines used by default in tests
debugDisableShadows = false;
await tester.pumpWidget(
MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(colorSchemeSeed: Colors.indigo),
home: const Demo(),
),
);
await tester.tap(find.byKey(Key(surface)));
await tester.pumpAndSettle();
await expectLater(
find.byType(MaterialApp),
matchesGoldenFile("../assets/screenshots/${surface}_$name.png"),
);
debugDisableShadows = true;
});
}
}
}