Skip to content
This repository was archived by the owner on Feb 25, 2024. It is now read-only.

Commit b92e2ab

Browse files
committed
Add golden test
Ref: #315
1 parent 0ddefad commit b92e2ab

28 files changed

+193
-0
lines changed

.github/workflows/flutter-ci.yml

+29
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,35 @@ jobs:
5858
- name: Check for any formatting issues
5959
run: dart format --set-exit-if-changed .
6060

61+
integration:
62+
runs-on: ubuntu-22.04
63+
steps:
64+
65+
- uses: actions/checkout@v2
66+
- uses: subosito/flutter-action@v2
67+
with:
68+
channel: 'stable'
69+
flutter-version: '3.10.x'
70+
71+
- name: Install dependencies
72+
run: |
73+
sudo apt update
74+
sudo apt -y install clang cmake curl libgtk-3-dev ninja-build pkg-config unzip xvfb
75+
sudo apt -y install fonts-noto-cjk fonts-ubuntu fonts-tibetan-machine
76+
77+
- name: Get dependencies
78+
run: flutter pub get
79+
80+
- name: Run integration tests
81+
run: xvfb-run -a -s '-screen 0 1280x800x24 +extension GLX' flutter test -d linux integration_test
82+
working-directory: example/
83+
84+
- uses: actions/upload-artifact@v3
85+
if: failure()
86+
with:
87+
name: failures
88+
path: example/integration_test/failures
89+
6190
pub:
6291
runs-on: ubuntu-20.04
6392
steps:

Makefile

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
.PHONY: goldens
2+
goldens:
3+
cd example && GDK_BACKEND=x11 GDK_SCALE=1 flutter test integration_test --update-goldens -d linux
+158
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,158 @@
1+
import 'dart:typed_data';
2+
3+
import 'package:flutter/material.dart';
4+
import 'package:flutter_test/flutter_test.dart';
5+
import 'package:integration_test/integration_test.dart';
6+
import 'package:path/path.dart' as path;
7+
import 'package:yaru/yaru.dart';
8+
import 'package:yaru_example/main.dart' as app;
9+
import 'package:yaru_example/main.dart';
10+
import 'package:yaru_example/view/home_page.dart';
11+
12+
// NOTE: run `flutter test --update-goldens integration_test` to update screenshots
13+
14+
const _kGoldenDiffTolerance = 0.005;
15+
16+
Future<void> main() async {
17+
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
18+
19+
goldenFileComparator = GoldenDiffComparator(
20+
path.join(
21+
path.fromUri((goldenFileComparator as LocalFileComparator).basedir),
22+
'yaru.dart',
23+
),
24+
tolerance: _kGoldenDiffTolerance,
25+
);
26+
27+
testWidgets('fonts', (tester) async {
28+
tester.runApp();
29+
await tester.pumpAndSettle();
30+
await tester.takeScreenshots('fonts');
31+
});
32+
33+
testWidgets('buttons', (tester) async {
34+
tester.runApp();
35+
await tester.pumpAndSettle();
36+
await tester.tap(find.text('Controls'));
37+
await tester.pump();
38+
await tester.takeScreenshots('buttons');
39+
});
40+
41+
testWidgets('checks', (tester) async {
42+
tester.runApp();
43+
await tester.pumpAndSettle();
44+
await tester.tap(find.text('Controls'));
45+
await tester.pump();
46+
await tester.tap(find.text('Checks'));
47+
await tester.pump();
48+
await tester.takeScreenshots('checks');
49+
});
50+
51+
testWidgets('switches', (tester) async {
52+
tester.runApp();
53+
await tester.pumpAndSettle();
54+
await tester.tap(find.text('Controls'));
55+
await tester.pump();
56+
await tester.tap(find.text('Switches'));
57+
await tester.pump();
58+
await tester.takeScreenshots('switches');
59+
});
60+
61+
testWidgets('text fields', (tester) async {
62+
tester.runApp();
63+
await tester.pumpAndSettle();
64+
await tester.tap(find.text('Text Fields'));
65+
await tester.pump();
66+
primaryFocus?.unfocus();
67+
await tester.pump();
68+
await tester.takeScreenshots('text-fields');
69+
});
70+
71+
testWidgets('containers', (tester) async {
72+
tester.runApp();
73+
await tester.pumpAndSettle();
74+
await tester.tap(find.text('Containers'));
75+
await tester.pump();
76+
await tester.takeScreenshots('containers');
77+
});
78+
}
79+
80+
extension on WidgetTester {
81+
void runApp() {
82+
view.devicePixelRatio = 1;
83+
view.physicalSize = const Size(600, 700);
84+
app.main();
85+
}
86+
87+
void selectTheme({
88+
YaruVariant? variant,
89+
bool? highContrast,
90+
ThemeMode? themeMode,
91+
}) async {
92+
final context = element(find.byType(HomePage));
93+
AppTheme.apply(
94+
context,
95+
variant: variant,
96+
highContrast: highContrast,
97+
themeMode: themeMode,
98+
);
99+
}
100+
101+
Future<void> takeScreenshots(String screen) async {
102+
for (final themeMode in [ThemeMode.light, ThemeMode.dark]) {
103+
selectTheme(
104+
variant: YaruVariant.orange,
105+
themeMode: themeMode,
106+
highContrast: false,
107+
);
108+
await pumpAndSettle();
109+
await takeScreenshot(screen);
110+
111+
selectTheme(themeMode: themeMode, highContrast: true);
112+
await pumpAndSettle();
113+
await takeScreenshot(screen);
114+
}
115+
}
116+
117+
Future<void> takeScreenshot(String screen) async {
118+
final context = element(find.byType(HomePage));
119+
final theme = AppTheme.of(context);
120+
final suffix = [
121+
if (theme.highContrast == true) 'high-contrast' else theme.variant?.name,
122+
theme.themeMode?.name,
123+
].join('-');
124+
125+
await expectLater(
126+
find.byType(MaterialApp),
127+
matchesGoldenFile('goldens/$screen-$suffix.png'),
128+
);
129+
}
130+
}
131+
132+
class GoldenDiffComparator extends LocalFileComparator {
133+
GoldenDiffComparator(
134+
String testFile, {
135+
required this.tolerance,
136+
}) : super(Uri.parse(testFile));
137+
138+
final double tolerance;
139+
140+
@override
141+
Future<bool> compare(Uint8List imageBytes, Uri golden) async {
142+
final ComparisonResult result = await GoldenFileComparator.compareLists(
143+
imageBytes,
144+
await getGoldenBytes(golden),
145+
);
146+
147+
if (!result.passed && result.diffPercent > tolerance) {
148+
final error = await generateFailureOutput(result, golden, basedir);
149+
throw FlutterError(error);
150+
}
151+
if (!result.passed) {
152+
debugPrint(
153+
'A tolerable difference of ${result.diffPercent * 100}% was found when comparing $golden.',
154+
);
155+
}
156+
return result.passed || result.diffPercent <= tolerance;
157+
}
158+
}
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

example/pubspec.yaml

+3
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ dev_dependencies:
1818
flutter_lints: ^2.0.1
1919
flutter_test:
2020
sdk: flutter
21+
integration_test:
22+
sdk: flutter
23+
path: ^1.8.3
2124

2225
flutter:
2326
uses-material-design: true

0 commit comments

Comments
 (0)