I have 3 different files/screens (the main, the login and the sign up), where the login and sign up are statefulwidgtes. i would like to perform widget testing in the screens, however, it seems like I can't get the widgets under login and sign up, every time I try I get the message:
Expected: exactly one matching node in the widget tree Actual: _WidgetTypeFinder:<zero widgets with type "ListView" (ignoring offstage widgets)> Which: means none were found but one was expected
Please note that in the example above, the ListView widget actually exist, but isn't being located by the tester.
Here is the code of the main widget
import "package:flutter/material.dart";
import 'package:loginscreen/setup/login.dart';
import 'package:firebase_core/firebase_core.dart';
// void main() => runApp(MyApp());
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.blue), home: LoginPage());
}
}
code for Loginpage:
import 'package:flutter/material.dart';
import './signup.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:loginscreen/pages/home.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class LoginPage extends StatefulWidget {
LoginPage({Key key}) : super(key: key);
@override
State<StatefulWidget> createState() => new _State();
}
class _State extends State<LoginPage> {
TextEditingController nameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
String email;
String password;
final _auth = FirebaseAuth.instance;
bool showSpinner = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Sign In'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(10),
child: Text(
'Firebase Authentication',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500,
fontSize: 30),
)),
Container(
padding: EdgeInsets.all(10),
child: TextField(
keyboardType: TextInputType.emailAddress,
onChanged: (value) {
email = value;
},
controller: nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email Address',
),
),
),
Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextField(
onChanged: (value) {
password = value;
},
obscureText: true,
controller: passwordController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
),
),
),
TextButton(
onPressed: () {
//forgot password screen
},
// textColor: Colors.blue,
child: Text('Forgot Password'),
),
Container(
height: 50,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
// ignore: deprecated_member_use
child: RaisedButton(
textColor: Colors.white,
color: Colors.blue,
child: Text('Login'),
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
await _auth.signInWithEmailAndPassword(
email: email, password: password);
setState(() {
showSpinner = true;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WelcomePage(),
),
);
} on FirebaseAuthException catch (e) {
if (e.code == 'user-not-found') {
print('No user found for that email.');
} else if (e.code == 'wrong-password') {
print('Wrong password provided for that user.');
}
}
},
),
),
Container(
child: Row(
children: [
Text('Don\'t not have account?'),
// ignore: deprecated_member_use
FlatButton(
textColor: Colors.blue,
child: Text(
'Sign Up',
style: TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(builder: (context) => SignupPage()),
);
},
)
],
mainAxisAlignment: MainAxisAlignment.center,
))
],
),
),
),
);
}
}
code for signup page:
import 'package:flutter/material.dart';
import './login.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:loginscreen/pages/home.dart';
import 'package:modal_progress_hud/modal_progress_hud.dart';
class SignupPage extends StatefulWidget {
@override
State<StatefulWidget> createState() => new _State();
}
class _State extends State<SignupPage> {
TextEditingController nameController = TextEditingController();
TextEditingController passwordController = TextEditingController();
final _auth = FirebaseAuth.instance;
String email;
String password;
String repeatpassword;
bool showSpinner = false;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Login Screen App'),
),
body: ModalProgressHUD(
inAsyncCall: showSpinner,
child: Padding(
padding: EdgeInsets.all(10),
child: ListView(
children: <Widget>[
Container(
alignment: Alignment.center,
padding: EdgeInsets.all(10),
child: Text(
'Firebase Authentication',
style: TextStyle(
color: Colors.blue,
fontWeight: FontWeight.w500,
fontSize: 30),
)),
Container(
padding: EdgeInsets.all(10),
child: TextField(
keyboardType: TextInputType.emailAddress,
onChanged: (value) {
email = value;
},
controller: nameController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email Address',
),
),
),
Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextField(
onChanged: (value) {
password = value;
},
obscureText: true,
controller: passwordController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password (must be at least 6 characters)',
),
),
),
Container(
padding: EdgeInsets.fromLTRB(10, 10, 10, 0),
child: TextField(
onChanged: (value) {
repeatpassword = value;
},
obscureText: true,
controller: passwordController,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Repeat Password',
),
),
),
TextButton(
onPressed: () {
//forgot password screen
},
// textColor: Colors.blue,
child: Text('Forgot Password'),
),
Container(
height: 50,
padding: EdgeInsets.fromLTRB(10, 0, 10, 0),
child: ElevatedButton(
// textColor: Colors.white,
// color: Colors.blue,
child: Text('Sign Up'),
onPressed: () async {
setState(() {
showSpinner = true;
});
try {
// UserCredential userCredential =
await _auth.createUserWithEmailAndPassword(
email: email, password: password);
setState(() {
showSpinner = false;
});
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => WelcomePage(),
),
);
} on FirebaseAuthException catch (e) {
if (e.code == 'weak-password') {
print('The password provided is too weak.');
} else if (e.code == 'email-already-in-use') {
print(
'The account already exists for that email.');
}
} catch (e) {
print(e);
}
},
),
),
Container(
child: Row(
children: <Widget>[
Text('Already have an account?'),
// ignore: deprecated_member_use
FlatButton(
textColor: Colors.blue,
child: Text(
'Sign in',
style: TextStyle(fontSize: 20),
),
onPressed: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => LoginPage()),
);
},
)
],
mainAxisAlignment: MainAxisAlignment.center,
))
],
))));
}
}
login page widget test (this is not working):
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:loginscreen/setup/login.dart';
void main() {
testWidgets(' ', (WidgetTester tester) async {
// add it to the widget tester
await tester.pumpWidget(LoginPage());
expect(find.byType(Text), findsOneWidget);
});
}
so my question is, how can I test the login and sign up stateful widgets? how do I get the widgets inside these screens?flu