Skip to content

Commit

Permalink
Merge pull request comigor#2 from Igor1201/poc/multiple-screenshots
Browse files Browse the repository at this point in the history
[POC] Multiple screenshots
  • Loading branch information
comigor authored Oct 6, 2018
2 parents 8a0183f + 223fe51 commit 31cd2dd
Show file tree
Hide file tree
Showing 7 changed files with 134 additions and 17 deletions.
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,6 @@ build/
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages

showcase/

21 changes: 20 additions & 1 deletion lib/components/my_widget.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,27 @@
import 'package:flutter/material.dart';

class MyWidget extends StatelessWidget {
final bool anotherBuild;
final double sliderValue;

MyWidget({
this.anotherBuild = false,
this.sliderValue = 2.0,
});

@override
Widget build(BuildContext context) {
if (anotherBuild) {
return Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(color: Colors.red, width: 40.0, height: 40.0),
Container(color: Colors.green, width: 40.0, height: 40.0),
Container(color: Colors.blue, width: 40.0, height: 40.0),
],
);
}

return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Expand All @@ -18,7 +37,7 @@ class MyWidget extends StatelessWidget {
value: true,
),
Slider(
value: 2.0,
value: sliderValue,
max: 7.0,
onChanged: (_) {},
),
Expand Down
30 changes: 21 additions & 9 deletions test/components/my_widget_test.dart
Original file line number Diff line number Diff line change
@@ -1,17 +1,29 @@
import 'package:flutter_test/flutter_test.dart';

import 'package:flutter/material.dart';
import 'package:showcase/components/my_widget.dart';
import '../helpers/golden_boundary.dart';
import '../helpers/showcase.dart';

void main() {
testWidgets('MyWidget golden', (WidgetTester tester) async {
await tester.pumpWidget(GoldenBoundary(
child: MyWidget(),
));
group('Showcase widgets', () {
final widgetList = [
MyWidget(),
MyWidget(anotherBuild: true),
MyWidget(sliderValue: 5.0),
];

await expectLater(
find.byType(MyWidget),
matchesGoldenFile('golden.png'),
showcaseWidgets(widgetList, customContainerBuilder: (child) => Container(
padding: EdgeInsets.all(12.0),
decoration: BoxDecoration(
color: Colors.amberAccent,
border: Border.all(
color: Colors.amber,
width: 2.0,
),
),
width: 800.0,
height: 240.0,
child: child,
),
);
});
}
17 changes: 17 additions & 0 deletions test/components/my_widget_test_golden.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import 'package:flutter_test/flutter_test.dart';

import 'package:showcase/components/my_widget.dart';
import '../helpers/golden_boundary.dart';

void main() {
testWidgets('MyWidget golden', (WidgetTester tester) async {
await tester.pumpWidget(GoldenBoundary(
child: MyWidget(),
));

await expectLater(
find.byType(MyWidget),
matchesGoldenFile('golden.png'),
);
});
}
30 changes: 23 additions & 7 deletions test/helpers/golden_boundary.dart
Original file line number Diff line number Diff line change
@@ -1,21 +1,37 @@
import 'package:flutter/material.dart';

typedef ContainerBuilder = Container Function(Widget child);

class GoldenBoundary extends StatelessWidget {
final Widget child;
final GlobalKey globalKey;
final ContainerBuilder customContainerBuilder;


GoldenBoundary({
@required this.child,
this.globalKey,
this.customContainerBuilder,
});

GoldenBoundary({@required this.child});
Widget _defaultContainerBuilder(Widget child) {
return Container(
padding: EdgeInsets.all(10.0),
width: 640.0,
height: 480.0,
child: child,
);
}

@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: RepaintBoundary(
child: Container(
padding: EdgeInsets.all(10.0),
width: 640.0,
height: 480.0,
child: child,
),
key: globalKey,
child: customContainerBuilder != null ?
customContainerBuilder(child) :
_defaultContainerBuilder(child),
),
),
);
Expand Down
1 change: 1 addition & 0 deletions test/helpers/showcase.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export './showcase_widgets.dart' show showcaseWidgets;
49 changes: 49 additions & 0 deletions test/helpers/showcase_widgets.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import 'dart:async';
import 'dart:typed_data';
import 'dart:io';
import 'dart:ui' as ui;

import 'package:flutter_test/flutter_test.dart';
import 'package:flutter/material.dart';
import 'package:flutter/rendering.dart';

import './golden_boundary.dart';

Future<Uint8List> capturePng(WidgetTester tester, GlobalKey key) async {
RenderRepaintBoundary boundary = key.currentContext.findRenderObject();
ui.Image image = await boundary.toImage();
ByteData byteData =
await image.toByteData(format: ui.ImageByteFormat.png);
return byteData.buffer.asUint8List();
}

Future<File> writeToFile(String path, Uint8List imageBytes) async {
final File output = File(path);
output.createSync(recursive: true);
return await output.writeAsBytes(imageBytes);
}

void makeTest(Widget widget, int index, {ContainerBuilder customContainerBuilder, String outDir}) async {
final strIndex = index.toString().padLeft(3, '0');
testWidgets('[$strIndex] Showcasing ${widget.toString()}', (WidgetTester tester) async {
// https://github.com/flutter/flutter/issues/17738#issuecomment-392237064
await tester.runAsync(() async {
final key = GlobalKey();

await tester.pumpWidget(GoldenBoundary(
globalKey: key,
child: widget,
customContainerBuilder: customContainerBuilder,
));

final screenshotBytes = await capturePng(tester, key);
await writeToFile('${outDir ?? 'showcase'}/${strIndex}_${widget.toString()}.png', screenshotBytes);
});
});
}

showcaseWidgets(List<Widget> widgets, {ContainerBuilder customContainerBuilder, String outDir}) {
widgets
.asMap()
.forEach((index, widget) => makeTest(widget, index, customContainerBuilder: customContainerBuilder, outDir: outDir));
}

0 comments on commit 31cd2dd

Please sign in to comment.