Skip to content

Commit dfa00a8

Browse files
authored
Merge pull request #99 from Akshatji800/random_widget_tests
Adds about_screen, base_app_bar, logout_alert and login screen widget tests.
2 parents 30fac82 + 74547da commit dfa00a8

8 files changed

+324
-5
lines changed

lib/Components/base_app_bar.dart

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ class BaseAppBar extends StatelessWidget implements PreferredSizeWidget {
1717
Widget build(BuildContext context) {
1818
return Consumer<HomeProvider>(builder: (context, homeModel, child) {
1919
return AppBar(
20+
key: Key('AppBar Key'),
2021
title: Image(
22+
key: Key('App icon key'),
2123
image: AssetImage(
2224
'assets/images/icon.png',
2325
),

lib/Components/logout_alert.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class LogOutAlert extends StatelessWidget {
1111
Widget build(BuildContext context) {
1212
final hp = MediaQuery.of(context).size.height;
1313
return AlertDialog(
14-
key: Key('Alert Dialog'),
14+
key: Key('Logout AlertDialog'),
1515
elevation: 0,
1616
backgroundColor: ThemeProvider.theme.primaryColorLight,
1717
shape: RoundedRectangleBorder(

lib/Pages/about_screen.dart

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ class _AboutScreenState extends State<AboutScreen> {
2121
width: double.infinity,
2222
),
2323
Image(
24+
key: Key('App icon asset image'),
2425
image: AssetImage(
2526
'assets/images/icon.png',
2627
),
@@ -33,15 +34,24 @@ class _AboutScreenState extends State<AboutScreen> {
3334
children: [
3435
SvgPicture.network(
3536
'https://img.shields.io/github/v/release/CCExtractor/Flood_Mobile?include_prereleases',
37+
key: Key('release badge key'),
3638
),
3739
SvgPicture.network(
38-
'https://img.shields.io/github/last-commit/CCExtractor/Flood_Mobile?label=commit'),
40+
'https://img.shields.io/github/last-commit/CCExtractor/Flood_Mobile?label=commit',
41+
key: Key('commit badge key'),
42+
),
3943
SvgPicture.network(
40-
'https://img.shields.io/github/workflow/status/CCExtractor/Flood_Mobile/Flutter%20CI'),
44+
'https://img.shields.io/github/workflow/status/CCExtractor/Flood_Mobile/Flutter%20CI',
45+
key: Key('build badge key'),
46+
),
4147
SvgPicture.network(
42-
'https://img.shields.io/github/issues/CCExtractor/Flood_Mobile'),
48+
'https://img.shields.io/github/issues/CCExtractor/Flood_Mobile',
49+
key: Key('issues badge key'),
50+
),
4351
SvgPicture.network(
44-
'https://img.shields.io/github/issues-pr/CCExtractor/Flood_Mobile?label=PR')
52+
'https://img.shields.io/github/issues-pr/CCExtractor/Flood_Mobile?label=PR',
53+
key: Key('PR badge key'),
54+
)
4555
],
4656
),
4757
SizedBox(
@@ -52,6 +62,7 @@ class _AboutScreenState extends State<AboutScreen> {
5262
children: [
5363
Text(
5464
'Flood is a monitoring service for various torrent clients. It\'s a Node.js service that communicates with your favorite torrent client and serves a decent mobile UI for administration. This project is based on the original Flood project.',
65+
key: Key('App info text key'),
5566
style: TextStyle(
5667
color: ThemeProvider.theme.textTheme.bodyText1?.color,
5768
fontSize: 15),
@@ -71,6 +82,7 @@ class _AboutScreenState extends State<AboutScreen> {
7182
),
7283
Text(
7384
'If you have a specific issue or bug, please file a GitHub issue. Please join the Flood Discord server to discuss feature requests and implementation details.',
85+
key: Key('Feedback text key'),
7486
style: TextStyle(
7587
color: ThemeProvider.theme.textTheme.bodyText1?.color,
7688
fontSize: 15),
@@ -90,6 +102,7 @@ class _AboutScreenState extends State<AboutScreen> {
90102
),
91103
Text(
92104
'Check out the Wiki for more information.',
105+
key: Key('More info text key'),
93106
style: TextStyle(
94107
color: ThemeProvider.theme.textTheme.bodyText1?.color,
95108
fontSize: 15),

lib/Pages/login_screen.dart

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ class _LoginScreenState extends State<LoginScreen> {
4646
child: Column(
4747
children: <Widget>[
4848
Image(
49+
key: Key('Flood Icon'),
4950
image: AssetImage(
5051
'assets/images/icon.png',
5152
),
@@ -75,6 +76,7 @@ class _LoginScreenState extends State<LoginScreen> {
7576
child: Stack(
7677
children: [
7778
TextFormField(
79+
key: Key('Url TextField'),
7880
controller: urlController,
7981
style: TextStyle(
8082
color: ThemeProvider
@@ -149,6 +151,7 @@ class _LoginScreenState extends State<LoginScreen> {
149151
),
150152
Container(
151153
child: TextFormField(
154+
key: Key('Username TextField'),
152155
controller: usernameController,
153156
style: TextStyle(
154157
color:
@@ -205,6 +208,7 @@ class _LoginScreenState extends State<LoginScreen> {
205208
child: Stack(
206209
children: <Widget>[
207210
TextFormField(
211+
key: Key('Password TextField'),
208212
controller: passwordController,
209213
style: TextStyle(
210214
color: ThemeProvider
@@ -331,6 +335,7 @@ class _LoginScreenState extends State<LoginScreen> {
331335
height: hp * 0.06,
332336
),
333337
IconButton(
338+
key: Key('Github Icon key'),
334339
icon: FaIcon(
335340
FontAwesomeIcons.github,
336341
),

test/about_screen_widget_test.dart

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
import 'dart:io';
2+
import 'package:flood_mobile/Constants/theme_provider.dart';
3+
import 'package:flood_mobile/Pages/about_screen.dart';
4+
import 'package:flood_mobile/Provider/api_provider.dart';
5+
import 'package:flood_mobile/Provider/client_provider.dart';
6+
import 'package:flood_mobile/Provider/home_provider.dart';
7+
import 'package:flood_mobile/Provider/sse_provider.dart';
8+
import 'package:flood_mobile/Provider/user_detail_provider.dart';
9+
import 'package:flutter_test/flutter_test.dart';
10+
import 'package:flutter/material.dart';
11+
import 'package:provider/provider.dart';
12+
13+
void main() {
14+
setUp(() {});
15+
setUpAll(() => HttpOverrides.global = null);
16+
Widget createWidgetUnderTest() {
17+
return MultiProvider(
18+
providers: [
19+
ChangeNotifierProvider<UserDetailProvider>(
20+
create: (context) => UserDetailProvider(),
21+
),
22+
ChangeNotifierProvider<HomeProvider>(
23+
create: (context) => HomeProvider(),
24+
),
25+
ChangeNotifierProvider<SSEProvider>(
26+
create: (context) => SSEProvider(),
27+
),
28+
ChangeNotifierProvider<ApiProvider>(
29+
create: (context) => ApiProvider(),
30+
),
31+
ChangeNotifierProvider<ClientSettingsProvider>(
32+
create: (context) => ClientSettingsProvider(),
33+
),
34+
ChangeNotifierProvider<ThemeProvider>(
35+
create: (context) => ThemeProvider(),
36+
),
37+
],
38+
child: Consumer<ThemeProvider>(
39+
builder: (context, themeProvider, _) {
40+
print(ThemeProvider.themeMode);
41+
return MaterialApp(
42+
home: Material(
43+
child: AboutScreen(),
44+
));
45+
},
46+
),
47+
);
48+
}
49+
50+
group("Check different widgets in about-screen", () {
51+
testWidgets("Check if widgets displayed correctly",
52+
(WidgetTester tester) async {
53+
await tester.pumpWidget(createWidgetUnderTest());
54+
expect(find.byKey(Key('App icon asset image')), findsOneWidget);
55+
expect(find.byKey(Key('release badge key')), findsOneWidget);
56+
expect(find.byKey(Key('commit badge key')), findsOneWidget);
57+
expect(find.byKey(Key('build badge key')), findsOneWidget);
58+
expect(find.byKey(Key('issues badge key')), findsOneWidget);
59+
expect(find.byKey(Key('PR badge key')), findsOneWidget);
60+
expect(find.byKey(Key('App info text key')), findsOneWidget);
61+
expect(find.text('Feedback'), findsOneWidget);
62+
expect(find.byKey(Key('Feedback text key')), findsOneWidget);
63+
expect(find.text('More Information'), findsOneWidget);
64+
expect(find.byKey(Key('More info text key')), findsOneWidget);
65+
});
66+
});
67+
}

test/base_app_bar_widget_test.dart

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
import 'package:flood_mobile/Components/base_app_bar.dart';
2+
import 'package:flood_mobile/Components/change_theme_button_widget.dart';
3+
import 'package:flood_mobile/Constants/theme_provider.dart';
4+
import 'package:flood_mobile/Provider/api_provider.dart';
5+
import 'package:flood_mobile/Provider/client_provider.dart';
6+
import 'package:flood_mobile/Provider/home_provider.dart';
7+
import 'package:flood_mobile/Provider/sse_provider.dart';
8+
import 'package:flood_mobile/Provider/user_detail_provider.dart';
9+
import 'package:flutter/material.dart';
10+
import 'package:flutter_test/flutter_test.dart';
11+
import 'package:provider/provider.dart';
12+
13+
void main() {
14+
setUp(() {});
15+
Widget createWidgetUnderTest() {
16+
return MultiProvider(
17+
providers: [
18+
ChangeNotifierProvider<UserDetailProvider>(
19+
create: (context) => UserDetailProvider(),
20+
),
21+
ChangeNotifierProvider<HomeProvider>(
22+
create: (context) => HomeProvider(),
23+
),
24+
ChangeNotifierProvider<SSEProvider>(
25+
create: (context) => SSEProvider(),
26+
),
27+
ChangeNotifierProvider<ApiProvider>(
28+
create: (context) => ApiProvider(),
29+
),
30+
ChangeNotifierProvider<ClientSettingsProvider>(
31+
create: (context) => ClientSettingsProvider(),
32+
),
33+
ChangeNotifierProvider<ThemeProvider>(
34+
create: (context) => ThemeProvider(),
35+
),
36+
],
37+
child: Consumer<ThemeProvider>(
38+
builder: (context, themeProvider, _) {
39+
print(ThemeProvider.themeMode);
40+
return MaterialApp(
41+
home: Material(
42+
child: BaseAppBar(appBar: AppBar()),
43+
));
44+
},
45+
),
46+
);
47+
}
48+
49+
group("Check different widgets in base_app_bar", () {
50+
testWidgets("Check if widgets displayed correctly",
51+
(WidgetTester tester) async {
52+
await tester.pumpWidget(createWidgetUnderTest());
53+
expect(find.byKey(Key('App icon key')), findsOneWidget);
54+
expect(find.byType(ChangeThemeButtonWidget), findsOneWidget);
55+
expect(find.byIcon(Icons.wb_sunny_rounded), findsOneWidget);
56+
expect(find.byIcon(Icons.mode_night_rounded), findsNothing);
57+
final themeFinder1 = find.byKey(Key('AppBar Key'));
58+
var theme1 = tester.firstWidget(themeFinder1) as AppBar;
59+
expect(theme1.backgroundColor, Color(0xff0E2537));
60+
await tester.tap(find.byIcon(Icons.wb_sunny_rounded));
61+
await tester.pumpAndSettle();
62+
expect(find.byIcon(Icons.mode_night_rounded), findsOneWidget);
63+
final themeFinder2 = find.byKey(Key('AppBar Key'));
64+
var theme2 = tester.firstWidget(themeFinder2) as AppBar;
65+
expect(theme2.backgroundColor, Colors.white);
66+
});
67+
});
68+
}

test/login_screen_widget_test.dart

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import 'dart:io';
2+
import 'package:flood_mobile/Constants/theme_provider.dart';
3+
import 'package:flood_mobile/Pages/login_screen.dart';
4+
import 'package:flood_mobile/Provider/api_provider.dart';
5+
import 'package:flood_mobile/Provider/client_provider.dart';
6+
import 'package:flood_mobile/Provider/home_provider.dart';
7+
import 'package:flood_mobile/Provider/sse_provider.dart';
8+
import 'package:flood_mobile/Provider/user_detail_provider.dart';
9+
import 'package:flutter/material.dart';
10+
import 'package:flutter_test/flutter_test.dart';
11+
import 'package:provider/provider.dart';
12+
13+
void main() {
14+
setUp(() {});
15+
setUpAll(() => HttpOverrides.global = null);
16+
Widget createWidgetUnderTest() {
17+
return MultiProvider(
18+
providers: [
19+
ChangeNotifierProvider<UserDetailProvider>(
20+
create: (context) => UserDetailProvider(),
21+
),
22+
ChangeNotifierProvider<HomeProvider>(
23+
create: (context) => HomeProvider(),
24+
),
25+
ChangeNotifierProvider<SSEProvider>(
26+
create: (context) => SSEProvider(),
27+
),
28+
ChangeNotifierProvider<ApiProvider>(
29+
create: (context) => ApiProvider(),
30+
),
31+
ChangeNotifierProvider<ClientSettingsProvider>(
32+
create: (context) => ClientSettingsProvider(),
33+
),
34+
ChangeNotifierProvider<ThemeProvider>(
35+
create: (context) => ThemeProvider(),
36+
),
37+
],
38+
child: Consumer<ThemeProvider>(
39+
builder: (context, themeProvider, _) {
40+
print(ThemeProvider.themeMode);
41+
return MaterialApp(
42+
home: Material(
43+
child: LoginScreen(),
44+
));
45+
},
46+
),
47+
);
48+
}
49+
50+
group("Check different widgets in login-screen", () {
51+
testWidgets("Check if widgets displayed correctly",
52+
(WidgetTester tester) async {
53+
await tester.pumpWidget(createWidgetUnderTest());
54+
expect(find.byKey(Key('Flood Icon')), findsOneWidget);
55+
expect(find.text('Welcome to Flood'), findsOneWidget);
56+
expect(find.text('Sign in to your account'), findsOneWidget);
57+
expect(find.byKey(Key('Url TextField')), findsOneWidget);
58+
expect(find.byIcon(Icons.link), findsOneWidget);
59+
expect(find.byIcon(Icons.paste), findsOneWidget);
60+
final urlControllerFinder = find.byKey(Key('Url TextField'));
61+
var urlController =
62+
tester.firstWidget(urlControllerFinder) as TextFormField;
63+
expect(urlController.controller?.text, 'http://localhost:3000');
64+
expect(find.byKey(Key('Username TextField')), findsOneWidget);
65+
expect(find.byIcon(Icons.person), findsOneWidget);
66+
expect(find.text('Username'), findsOneWidget);
67+
expect(find.byKey(Key('Password TextField')), findsOneWidget);
68+
expect(find.text('Password'), findsOneWidget);
69+
expect(find.byIcon(Icons.lock_outline), findsOneWidget);
70+
expect(find.byIcon(Icons.visibility), findsOneWidget);
71+
await tester.tap(find.byIcon(Icons.visibility));
72+
await tester.pumpAndSettle();
73+
expect(find.byIcon(Icons.visibility_off), findsOneWidget);
74+
expect(find.widgetWithText(ElevatedButton, 'Login'), findsOneWidget);
75+
expect(find.byKey(Key('Github Icon key')), findsOneWidget);
76+
});
77+
78+
testWidgets("Check if validators working correctly",
79+
(WidgetTester tester) async {
80+
await tester.pumpWidget(createWidgetUnderTest());
81+
await tester.enterText(find.byKey(Key('Url TextField')), '');
82+
await tester.tap(find.widgetWithText(ElevatedButton, 'Login'));
83+
await tester.pumpAndSettle();
84+
expect(find.text('Field cannot be empty'), findsNWidgets(3));
85+
await tester.enterText(find.byKey(Key('Url TextField')), 'test url');
86+
await tester.tap(find.widgetWithText(ElevatedButton, 'Login'));
87+
await tester.pumpAndSettle();
88+
expect(find.text('Field cannot be empty'), findsNWidgets(2));
89+
await tester.enterText(
90+
find.byKey(Key('Username TextField')), 'test username');
91+
await tester.tap(find.widgetWithText(ElevatedButton, 'Login'));
92+
await tester.pumpAndSettle();
93+
expect(find.text('Field cannot be empty'), findsNWidgets(1));
94+
await tester.enterText(
95+
find.byKey(Key('Password TextField')), 'test password');
96+
await tester.tap(find.widgetWithText(ElevatedButton, 'Login'));
97+
await tester.pumpAndSettle();
98+
expect(find.text('Field cannot be empty'), findsNWidgets(0));
99+
});
100+
});
101+
}

0 commit comments

Comments
 (0)