Skip to content

Commit

Permalink
Merge pull request #68 from moonytoes29/feature/DeviceBuilder
Browse files Browse the repository at this point in the history
Adds 'DeviceBuilder' factory and helper 'multiDeviceGolden' method to create single golden files for multiple Device configurations and scenarios
  • Loading branch information
coreysprague authored Oct 30, 2020
2 parents c1028fd + 869496e commit 43445ee
Show file tree
Hide file tree
Showing 15 changed files with 742 additions and 15 deletions.
95 changes: 86 additions & 9 deletions packages/golden_toolkit/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,23 @@ It is highly recommended to look at sample tests here: [golden_builder_test.dart

## Table of Contents

- [Key Features](#Key-Features)
- [GoldenBuilder](#goldenbuilder)
- [multiScreenGolden](#multiscreengolden)
- [Getting Started](#Getting-Started)
- [Setup](#Setup)
- [Loading Fonts](#Loading-Fonts)
- [testGoldens()](#testGoldens)
- [Pumping Widgets](#Pumping-Widgets)
- [Configuration](#Configuration)
- [Golden Toolkit](#golden-toolkit)
- [Table of Contents](#table-of-contents)
- [Key Features](#key-features)
- [GoldenBuilder](#goldenbuilder)
- [DeviceBuilder](#devicebuilder)
- [multiScreenGolden](#multiscreengolden)
- [Getting Started](#getting-started)
- [Setup](#setup)
- [Add the failures folder to .gitignore](#add-the-failures-folder-to-gitignore)
- [Configure VS Code](#configure-vs-code)
- [Loading Fonts](#loading-fonts)
- [Caveats](#caveats)
- [testGoldens()](#testgoldens)
- [Pumping Widgets](#pumping-widgets)
- [Configuration](#configuration)
- [License Information](#license-information)
- [3rd Party Software Included or Modified in Project](#3rd-party-software-included-or-modified-in-project)

## Key Features

Expand Down Expand Up @@ -66,6 +74,75 @@ The output of this test will be this golden file: `weather_accessibility.png`:

See tests for usage examples: [golden_builder_test.dart](example/test/golden_builder_test.dart)


### DeviceBuilder

DeviceBuilder class is like the GoldenBuilder except that it constrains scenario widget sizes to Device configurations. This removes the need
to specify a column or grid based layout.

It will generate a widget that lays out its scenarios vertically and the Device configurations of those scenarios horizontally. All in one single
golden png file.

In the case of a single scenario the helper method of (#multiDeviceGolden) can simplify DeviceBuilder usage. For multiple scenarios, DeviceBuilder
can help

```dart
testGoldens('DeviceBuilder - multiple scenarios - with onCreate',
(tester) async {
final builder = DeviceBuilder()
..overrideDevicesForAllScenarios(devices: [
Device.phone,
Device.iphone11,
Device.tabletPortrait,
Device.tabletLandscape,
])
..addScenario(
widget: FlutterDemoPage(),
name: 'default page',
)
..addScenario(
widget: FlutterDemoPage(),
name: 'tap once',
onCreate: (scenarioWidgetKey) async {
final finder = find.descendant(
of: find.byKey(scenarioWidgetKey),
matching: find.byIcon(Icons.add),
);
expect(finder, findsOneWidget);
await tester.tap(finder);
},
)
..addScenario(
widget: FlutterDemoPage(),
name: 'tap five times',
onCreate: (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');
});
```

This will generate the following golden:

`flutter_demo_page_multiple_scenarios.png`

![example widget captured](example/test/goldens/flutter_demo_page_multiple_scenarios.png)


### multiScreenGolden

The multiScreenGolden assertion is used to capture multiple goldens of a single widget using different simulated device sizes & characteristics.
Expand Down
1 change: 1 addition & 0 deletions packages/golden_toolkit/example/lib/example.dart
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export 'src/flutter_demo_page.dart';
export 'src/weather_widgets.dart';
63 changes: 63 additions & 0 deletions packages/golden_toolkit/example/lib/src/flutter_demo_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import 'package:flutter/material.dart';

/// Counter page from flutters default generated app
class FlutterDemoPage extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: const _MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}

class _MyHomePage extends StatefulWidget {
const _MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@override
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<_MyHomePage> {
int _counter = 0;

void _incrementCounter() {
setState(() {
_counter++;
});
}

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headline4,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/// license that can be found in the LICENSE file or at
/// https://opensource.org/licenses/BSD-3-Clause
/// ***************************************************
// ignore_for_file: public_member_api_docs

import 'dart:ui';
Expand Down
85 changes: 85 additions & 0 deletions packages/golden_toolkit/example/test/flutter_demo_page_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:golden_toolkit/golden_toolkit.dart';

// ignore: avoid_relative_lib_imports
import '../lib/src/flutter_demo_page.dart';

void main() {
testGoldens('DeviceBuilder - one scenario - default devices', (tester) async {
final builder = DeviceBuilder()
..addScenario(
widget: FlutterDemoPage(),
name: 'default page',
);

await tester.pumpDeviceBuilder(builder);

await screenMatchesGolden(tester, 'flutter_demo_page_single_scenario');
});

testGoldens('DeviceBuilder - one scenario - override devices', (tester) async {
final builder = DeviceBuilder()
..overrideDevicesForAllScenarios(devices: [
Device.phone,
Device.iphone11,
Device.tabletPortrait,
Device.tabletLandscape,
])
..addScenario(
widget: FlutterDemoPage(),
name: 'default page',
);

await tester.pumpDeviceBuilder(builder);

await screenMatchesGolden(tester, 'flutter_demo_page_single_scenario_more_devices');
});

testGoldens('DeviceBuilder - multiple scenarios - with onCreate', (tester) async {
final builder = DeviceBuilder()
..overrideDevicesForAllScenarios(devices: [
Device.phone,
Device.iphone11,
Device.tabletPortrait,
Device.tabletLandscape,
])
..addScenario(
widget: FlutterDemoPage(),
name: 'default page',
)
..addScenario(
widget: FlutterDemoPage(),
name: 'tap once',
onCreate: (scenarioWidgetKey) async {
final finder = find.descendant(
of: find.byKey(scenarioWidgetKey),
matching: find.byIcon(Icons.add),
);
expect(finder, findsOneWidget);
await tester.tap(finder);
},
)
..addScenario(
widget: FlutterDemoPage(),
name: 'tap five times',
onCreate: (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');
});
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion packages/golden_toolkit/golden_toolkit.code-workspace
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
"editor.tabSize": 2,
"editor.insertSpaces": false,
"editor.formatOnSave": true,
"editor.wordWrapColumn": 120
"editor.wordWrapColumn": 120,
"dart.lineLength": 120
}
}
1 change: 1 addition & 0 deletions packages/golden_toolkit/lib/golden_toolkit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ library golden_toolkit;

export 'src/configuration.dart';
export 'src/device.dart';
export 'src/device_builder.dart';
export 'src/font_loader.dart' show loadAppFonts;
export 'src/golden_builder.dart';
export 'src/multi_screen_golden.dart';
Expand Down
Loading

0 comments on commit 43445ee

Please sign in to comment.