Problem statement:
Capturing golden files for a screen that has multiple differences across device sizes and multiple complicated ui states.
Current package says to use 'multiScreenGolden' for the same widget rendered in multiple device sizes (i.e Device.phone, Device.tabletLandscape). This however, produces a single png golden file per device. When adding multiple scenarios/states for that screen and needing still to see across multiple devices, this can grow the number of files considerably.
Proposed solution:
DeviceBuilder factory
The DeviceBuilder class allows user to create multiple scenarios across multiple devices in a single png golden file. The example added was around the default flutter counter view and capturing ui based on user taps.
testGoldens('DeviceBuilder - multiple scenarios - with afterPump',
(tester) async {
final builder = DeviceBuilder()
..overrideDevicesForAllScenarios(devices: [
Device.phone,
Device.iphone11,
Device.tabletPortrait,
Device.tabletLandscape,
])
..addDeviceScenario(
widget: FlutterDemoPage(),
name: 'default page',
)
..addDeviceScenario(
widget: FlutterDemoPage(),
name: 'tap once',
afterPump: (scenarioWidgetKey) async {
final finder = find.descendant(
of: find.byKey(scenarioWidgetKey),
matching: find.byIcon(Icons.add),
);
expect(finder, findsOneWidget);
await tester.tap(finder);
},
)
..addDeviceScenario(
widget: FlutterDemoPage(),
name: 'tap five times',
afterPump: (scenarioWidgetKey) async {
final finder = find.descendant(
of: find.byKey(scenarioWidgetKey),
matching: find.byIcon(Icons.add),
);
expect(finder, findsOneWidget);
await tester.tap(finder);
await tester.tap(finder);
await tester.tap(finder);
await tester.tap(finder);
await tester.tap(finder);
},
);
await tester.pumpDeviceBuilder(builder);
await screenMatchesGolden(tester, 'flutter_demo_page_multiple_scenarios');
});
The DeviceBuilder exposes an 'afterPump' callback to perform any interactions required to render the scenario across all device sizes. For simpler widgets/screens where a ui state can be instantiated statically through construction, then the 'afterPump' functionality wouldn't be needed.
This produces a single golden file:
The simplest use of this doesn't require you to call overrideDevicesForAllScenarios
, as by default it will use GoldenToolkit.configuration.defaultDevices
. You can also omit scenario name
parameter to.
final builder = DeviceBuilder()..addDeviceScenario( widget: FlutterDemoPage());
multiDeviceGolden
This is a helper method much like the existing multiScreenGolden
, except that it produces one single golden file instead of multiple per device. This method can be used if you just one a single scenario and don't need to use DeviceBuilder
directly.
testGoldens('multiDeviceGolden', (tester) async {
await multiDeviceGolden(
tester,
'flutter_demo_multi_device_golden',
widget: FlutterDemoPage(),
afterPump: (scenarioWidgetKey) async {
final finder = find.descendant(
of: find.byKey(scenarioWidgetKey),
matching: find.byIcon(Icons.add),
);
expect(finder, findsOneWidget);
await tester.tap(finder);
},
);
});
Other fixes
The current tests were not passing on latest flutter stable 1.22.1. Had to regenerate some golden files. Also had issues with analysis options when opening root folder and looking at weather_widgets.dart. So ignored some issues in there to help analysis step pass.