Skip to content

Commit bb11823

Browse files
author
Ryosuke Yabuki
authored
Merge pull request #84 from launchableinc/flutter-example
Add flutter example
2 parents ee1e7ea + ad0afea commit bb11823

File tree

8 files changed

+428
-0
lines changed

8 files changed

+428
-0
lines changed

.github/workflows/flutter.yaml

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
name: Flutter
2+
3+
on:
4+
push:
5+
branches: [master]
6+
paths:
7+
- "flutter/**"
8+
- ".github/workflows/flutter.yml"
9+
pull_request:
10+
paths:
11+
- "flutter/**"
12+
- ".github/workflows/flutter.yml"
13+
14+
15+
env:
16+
LAUNCHABLE_TOKEN: ${{ secrets.LAUNCHABLE_TOKEN_FLUTTER }}
17+
LAUNCHABLE_DEBUG: 1
18+
LAUNCHABLE_REPORT_ERROR: 1
19+
20+
jobs:
21+
tests:
22+
runs-on: ubuntu-24.04
23+
defaults:
24+
run:
25+
working-directory: flutter
26+
steps:
27+
- uses: actions/checkout@v4
28+
- uses: actions/setup-python@v5
29+
with:
30+
cache: 'pip'
31+
- name: Install dependencies
32+
run: |
33+
python -m pip install --upgrade pip
34+
pip install wheel setuptools_scm
35+
pip install launchable
36+
- name: Set up Flutter
37+
uses: subosito/flutter-action@v2
38+
with:
39+
flutter-version: '3.24.4'
40+
- run: "launchable verify"
41+
- name: Record commits and build
42+
run: 'launchable record build --name "$GITHUB_RUN_ID" --source ..' # care for working-directory path
43+
# Skip #TODO(Konboi): enable subset
44+
#- name: Subset
45+
# run: launchable subset --confidence 100% flutter test/**/*_test.dart > launchable-subset.txt
46+
- name: Install dependencies
47+
run: flutter pub get
48+
- name: Test
49+
run: flutter test --machine > report.json
50+
- name: Record
51+
run: launchable record tests --base $(pwd) flutter report.json
52+
if: always()

flutter/.gitignore

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# See https://www.dartlang.org/guides/libraries/private-files
2+
3+
# Files and directories created by pub
4+
.dart_tool/
5+
.packages
6+
build/
7+
# If you're building an application, you may want to check-in your pubspec.lock
8+
pubspec.lock
9+
10+
# Directory created by dartdoc
11+
# If you don't generate documentation locally you can remove this line.
12+
doc/api/
13+
14+
# dotenv environment variables file
15+
.env*
16+
17+
# Avoid committing generated Javascript files:
18+
*.dart.js
19+
*.info.json # Produced by the --dump-info flag.
20+
*.js # When generated by dart2js. Don't specify *.js if your
21+
# project includes source files written in JavaScript.
22+
*.js_
23+
*.js.deps
24+
*.js.map
25+
26+
.flutter-plugins
27+
.flutter-plugins-dependencies

flutter/README.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# flutter example
2+
3+
## Recording test results
4+
5+
```sh
6+
$ BUILD_NAME=test
7+
$ launchable record build --name ${BUILD_NAME}
8+
# will print collected commit information
9+
# Please install dependencies before execute test
10+
$ flutter pub get
11+
# Execute test with `--machine` option
12+
$ flutter test --machine > report.json
13+
$ launchable record tests flutter report.json
14+
Launchable recorded tests for build 11884403890 (test session 3441847) to workspace launchableinc/rocket-car-flutter from 1 files:
15+
16+
| Files found | Tests found | Tests passed | Tests failed | Total duration (min) |
17+
|---------------|---------------|----------------|----------------|------------------------|
18+
| 1 | 3 | 1 | 1 | 0.40 |
19+
20+
Visit https://app.launchableinc.com/organizations/launchableinc/workspaces/rocket-car-flutter/test-sessions/3441847 to view uploaded test results (or run `launchable inspect tests --test-session-id 3441847`)
21+
```
22+
23+
___
24+
25+
## Subsettinging your test runs
26+
27+
```sh
28+
$ BUILD_NAME=test
29+
$ CONFIDENCE="50%"
30+
$ launchable subset --build ${BUILD_NAME} --confidence ${CONFIDENCE} \
31+
flutter test/**/*_test.dart > subset.txt
32+
33+
$ flutter test $(cat subset.txt) --machine > report.json
34+
```
35+
36+
37+

flutter/lib/main.dart

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
import 'package:flutter/material.dart';
2+
3+
void main() {
4+
runApp(const MyApp());
5+
}
6+
7+
class MyApp extends StatelessWidget {
8+
const MyApp({super.key});
9+
10+
// This widget is the root of your application.
11+
@override
12+
Widget build(BuildContext context) {
13+
return MaterialApp(
14+
title: 'Flutter Demo',
15+
theme: ThemeData(
16+
// This is the theme of your application.
17+
//
18+
// TRY THIS: Try running your application with "flutter run". You'll see
19+
// the application has a purple toolbar. Then, without quitting the app,
20+
// try changing the seedColor in the colorScheme below to Colors.green
21+
// and then invoke "hot reload" (save your changes or press the "hot
22+
// reload" button in a Flutter-supported IDE, or press "r" if you used
23+
// the command line to start the app).
24+
//
25+
// Notice that the counter didn't reset back to zero; the application
26+
// state is not lost during the reload. To reset the state, use hot
27+
// restart instead.
28+
//
29+
// This works for code too, not just values: Most code changes can be
30+
// tested with just a hot reload.
31+
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
32+
useMaterial3: true,
33+
),
34+
home: const MyHomePage(title: 'Flutter Demo Home Page'),
35+
);
36+
}
37+
}
38+
39+
class MyHomePage extends StatefulWidget {
40+
const MyHomePage({super.key, required this.title});
41+
42+
// This widget is the home page of your application. It is stateful, meaning
43+
// that it has a State object (defined below) that contains fields that affect
44+
// how it looks.
45+
46+
// This class is the configuration for the state. It holds the values (in this
47+
// case the title) provided by the parent (in this case the App widget) and
48+
// used by the build method of the State. Fields in a Widget subclass are
49+
// always marked "final".
50+
51+
final String title;
52+
53+
@override
54+
State<MyHomePage> createState() => _MyHomePageState();
55+
}
56+
57+
class _MyHomePageState extends State<MyHomePage> {
58+
int _counter = 0;
59+
60+
void _incrementCounter() {
61+
setState(() {
62+
// This call to setState tells the Flutter framework that something has
63+
// changed in this State, which causes it to rerun the build method below
64+
// so that the display can reflect the updated values. If we changed
65+
// _counter without calling setState(), then the build method would not be
66+
// called again, and so nothing would appear to happen.
67+
_counter++;
68+
});
69+
}
70+
71+
@override
72+
Widget build(BuildContext context) {
73+
// This method is rerun every time setState is called, for instance as done
74+
// by the _incrementCounter method above.
75+
//
76+
// The Flutter framework has been optimized to make rerunning build methods
77+
// fast, so that you can just rebuild anything that needs updating rather
78+
// than having to individually change instances of widgets.
79+
return Scaffold(
80+
appBar: AppBar(
81+
// TRY THIS: Try changing the color here to a specific color (to
82+
// Colors.amber, perhaps?) and trigger a hot reload to see the AppBar
83+
// change color while the other colors stay the same.
84+
backgroundColor: Theme.of(context).colorScheme.inversePrimary,
85+
// Here we take the value from the MyHomePage object that was created by
86+
// the App.build method, and use it to set our appbar title.
87+
title: Text(widget.title),
88+
),
89+
body: Center(
90+
// Center is a layout widget. It takes a single child and positions it
91+
// in the middle of the parent.
92+
child: Column(
93+
// Column is also a layout widget. It takes a list of children and
94+
// arranges them vertically. By default, it sizes itself to fit its
95+
// children horizontally, and tries to be as tall as its parent.
96+
//
97+
// Column has various properties to control how it sizes itself and
98+
// how it positions its children. Here we use mainAxisAlignment to
99+
// center the children vertically; the main axis here is the vertical
100+
// axis because Columns are vertical (the cross axis would be
101+
// horizontal).
102+
//
103+
// TRY THIS: Invoke "debug painting" (choose the "Toggle Debug Paint"
104+
// action in the IDE, or press "p" in the console), to see the
105+
// wireframe for each widget.
106+
mainAxisAlignment: MainAxisAlignment.center,
107+
children: <Widget>[
108+
const Text(
109+
'You have pushed the button this many times:',
110+
),
111+
Text(
112+
'$_counter',
113+
style: Theme.of(context).textTheme.headlineMedium,
114+
),
115+
],
116+
),
117+
),
118+
floatingActionButton: FloatingActionButton(
119+
onPressed: _incrementCounter,
120+
tooltip: 'Increment',
121+
child: const Icon(Icons.add),
122+
), // This trailing comma makes auto-formatting nicer for build methods.
123+
);
124+
}
125+
}

flutter/pubspec.yaml

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
name: rocket_car_flutter
2+
description: "A new Flutter project."
3+
# The following line prevents the package from being accidentally published to
4+
# pub.dev using `flutter pub publish`. This is preferred for private packages.
5+
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
6+
7+
# The following defines the version and build number for your application.
8+
# A version number is three numbers separated by dots, like 1.2.43
9+
# followed by an optional build number separated by a +.
10+
# Both the version and the builder number may be overridden in flutter
11+
# build by specifying --build-name and --build-number, respectively.
12+
# In Android, build-name is used as versionName while build-number used as versionCode.
13+
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
14+
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
15+
# Read more about iOS versioning at
16+
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
17+
# In Windows, build-name is used as the major, minor, and patch parts
18+
# of the product and file versions while build-number is used as the build suffix.
19+
version: 1.0.0+1
20+
21+
environment:
22+
sdk: ^3.5.4
23+
24+
# Dependencies specify other packages that your package needs in order to work.
25+
# To automatically upgrade your package dependencies to the latest versions
26+
# consider running `flutter pub upgrade --major-versions`. Alternatively,
27+
# dependencies can be manually updated by changing the version numbers below to
28+
# the latest version available on pub.dev. To see which dependencies have newer
29+
# versions available, run `flutter pub outdated`.
30+
dependencies:
31+
flutter:
32+
sdk: flutter
33+
34+
35+
# The following adds the Cupertino Icons font to your application.
36+
# Use with the CupertinoIcons class for iOS style icons.
37+
cupertino_icons: ^1.0.8
38+
39+
dev_dependencies:
40+
test: ^1.25.0
41+
junitreport: ^2.0.0
42+
43+
flutter_test:
44+
sdk: flutter
45+
46+
# The "flutter_lints" package below contains a set of recommended lints to
47+
# encourage good coding practices. The lint set provided by the package is
48+
# activated in the `analysis_options.yaml` file located at the root of your
49+
# package. See that file for information about deactivating specific lint
50+
# rules and activating additional ones.
51+
flutter_lints: ^4.0.0
52+
53+
# For information on the generic Dart part of this file, see the
54+
# following page: https://dart.dev/tools/pub/pubspec
55+
56+
# The following section is specific to Flutter packages.
57+
flutter:
58+
59+
# The following line ensures that the Material Icons font is
60+
# included with your application, so that you can use the icons in
61+
# the material Icons class.
62+
uses-material-design: true
63+
64+
# To add assets to your application, add an assets section, like this:
65+
# assets:
66+
# - images/a_dot_burr.jpeg
67+
# - images/a_dot_ham.jpeg
68+
69+
# An image asset can refer to one or more resolution-specific "variants", see
70+
# https://flutter.dev/to/resolution-aware-images
71+
72+
# For details regarding adding assets from package dependencies, see
73+
# https://flutter.dev/to/asset-from-package
74+
75+
# To add custom fonts to your application, add a fonts section here,
76+
# in this "flutter" section. Each entry in this list should have a
77+
# "family" key with the font family name, and a "fonts" key with a
78+
# list giving the asset and other descriptors for the font. For
79+
# example:
80+
# fonts:
81+
# - family: Schyler
82+
# fonts:
83+
# - asset: fonts/Schyler-Regular.ttf
84+
# - asset: fonts/Schyler-Italic.ttf
85+
# style: italic
86+
# - family: Trajan Pro
87+
# fonts:
88+
# - asset: fonts/TrajanPro.ttf
89+
# - asset: fonts/TrajanPro_Bold.ttf
90+
# weight: 700
91+
#
92+
# For details regarding fonts from package dependencies,
93+
# see https://flutter.dev/to/font-from-package
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// This is a basic Flutter widget test.
2+
//
3+
// To perform an interaction with a widget in your test, use the WidgetTester
4+
// utility in the flutter_test package. For example, you can send tap and scroll
5+
// gestures. You can also use WidgetTester to find child widgets in the widget
6+
// tree, read text, and verify that the values of widget properties are correct.
7+
8+
import 'package:flutter/material.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
11+
import 'package:rocket_car_flutter/main.dart';
12+
13+
void main() {
14+
testWidgets('Counter increments smoke failure test',
15+
(WidgetTester tester) async {
16+
// Build our app and trigger a frame.
17+
await tester.pumpWidget(const MyApp());
18+
19+
// Verify that our counter starts at 0.
20+
expect(find.text('0'), findsOneWidget);
21+
expect(find.text('1'), findsNothing);
22+
23+
// Tap the '+' icon and trigger a frame.
24+
await tester.tap(find.byIcon(Icons.add));
25+
await tester.pump();
26+
27+
// Verify that our counter has incremented.
28+
expect(find.text('0'), findsNothing);
29+
// Failure case
30+
expect(find.text('2'), findsOneWidget);
31+
});
32+
}

0 commit comments

Comments
 (0)