Selecting Email Account from google_sign_in during Flutter integration testing - flutter

I was trying to test sign-in to my home screen for my flutter app. I am using the google-signin ( https://pub.dev/packages/google_sign_in) package from Flutter to perform login and authentication. So once the login button is pressed, a popup appears asking the user to select the user account. At that point, I am unable to control the tap as this dialog screen is generated by the plugin. How do I implement selection of the user account in this case ?
test('Test Login', () async {
final Timeline timeline = await driver.traceAction(() async {
await driver.tap(find.byValueKey('GoogleLogin'));
await driver.tap(find.text('myemail#gmail.com')); // This will not work !!!
});
TimelineSummary.summarize(timeline)
..writeSummaryToFile('home_scroll_perf', pretty: true)
..writeTimelineToFile('home_scroll_perf', pretty: true);
});
In my opinion, this could be a problem when testing with any third party plugin. Please help.

It seems that the issue is still existing. There is no available workaround yet. Keep an eye on this GitHub post as this is closely monitored by the Flutter team.

Try Patrol, it lets you very easily interact with native UIs such as the Google sign-in dialog.
Below is a rough example of how I'd approach this. I'm going to assume that you're already signed in to a Google account, so the only thing you have to do is to select an email from the dialog.
// integration_test/sign_in_test.dart
void main() {
patrolTest(
'signs in with Google',
nativeAutomation: true,
(PatrolTester $) async {
await $.pumpWidgeAndSettle(YourAppWidget());
await $('Sign in with Google').tap();
await $.native.tap(Selector(text: 'your.email#gmail.com'));
await $.pumpAndSettle();
// should be signed in now
},
);
}
Remember: that integration tests has to be run with patrol drive, not flutter test integration_test.

Related

Flutter Web Firebase Auth's persistence doesn't work on PWA

I have developed a Flutter Web app that uses Firebase Authentication in order to sign in users to the app.
I've declared the Firebase Authentication persistence field so that the app will remember and auto-login the user when he revisits the Flutter Web app's URL, and won't be required to re-login every time he launches the URL.
It all works fine on a regular browser, but when the user generates a PWA (for example, clicking "Add to Home Screen" on iOS devices to save the website as PWA), the persistence feature stops working, and the user is required to re-login every time he opens the PWA.
Is there a way to add Firebase Authentication's persistence feature to a PWA? And if not, is there a way to prevent generating a PWA (and saving the Flutter Web app as a regular browser URL when clicking "Add to Home Screen" button on iOS, for example)?
Thank you!
To solve the persistence problem, add a listener:
FirebaseAuth.instance.idTokenChanges().listen((User? user) async {
if (user == null) {
// Function for user not logged in here. Do not write function to change page here.
} else {
// As it's a Future it will take a while to process the user's information, so it
will call the function after it's done.
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => Home()));
}
}
This is an example I made and it worked, use controllers to change the status, put some function to wait for the information to be processed.
Hope this helps. Any questions, at your disposal.

App not setup: This app is still in development mode - Login through Facebook 2021

I'm trying to create a Login through Facebook button in my Flutter project using Firebase. I added all the things Facebook asked and I have also set my app in Live mode. But when I try to Login, it says
App not setup: This app is still in development mode.
Here's the code I've used in my flutter project:
Future<UserCredential> _signInWithFacebook() async {
final AccessToken result = await FacebookAuth.instance.login();
final FacebookAuthCredential facebookAuthCredential =
FacebookAuthProvider.credential(result.token);
return await FirebaseAuth.instance.signInWithCredential(facebookAuthCredential);
}
How do I solve this?

Flutter integration test firebase auth (email link or google sign in)

I'm adding integration testing (using the integration_test package) to my app but I am running into a problem.
Let me explain. The first step when my app launch is authentication for which I have 3 options: firebase email link, firebase google sign in, and firebase facebook sign in.
What is blocking me is that all these sign in methods require actions outside of the main app dart code and thus are not accessible by flutter driver.
Am I missing something here? And if not how should that case be handled?
Cheers!
To make the test less flaky i would recommend to not rely on an internet connection or a third party (like Firebase or Google login).
I would advise to use a Mock for this. So when you try to login to your test you send a fake response, and in that way you can continue using the app.
The following article explains how to use a mock:
https://medium.com/stuart-engineering/mocking-integration-tests-with-flutter-af3b6ba846c7
You can use Patrol – it lets you interact with native system UI from within your Flutter integration tests. Example:
import 'package:flutter_test/flutter_test.dart';
import 'package:patrol/patrol.dart';
void main() {
patrolTest(
'signs in',
nativeAutomation: true,
(PatrolTester $) async {
await $.native.enterText(
Selector(textContains: 'Email'),
text: 'tester#awesomeapp.pl'),
);
await $.native.enterText(
Selector(textContains: 'Password'),
text: 'ny4ncat'),
);
await $.native.tap(Selector(text: 'Continue'));
// you should be signed in
});
}
You can add the fourth way of signing in - using username and password. Firebase should support this kind of very common situation, so you can do it within lines of code.
If you do not want the end users to login by password, you can simply disable this method in production build and only enable it in debug build.
Another way is to mock your authentication system. In other words, when doing testing, you have a button called "fake sign in", and your integration test driver just click that button.

Is there any twitter authentication for flutter web?

so I want users to be able to sign up with their twitter account on my flutter website.
I've found this package (https://pub.dev/packages/flutter_twitter) but I've tried it and it does not work on flutter web, only on mobiles.
So, do I have to make this auth myself? If so, how could i do that?
You can use firebase Authentication sign-in method with twitter
For Flutter Web, the flutter_twitter package does NOT work, unfortunately. However, using firebase_auth and firebase_core will work for Flutter Web:
Future<bool> signInWithTwitter() async {
final userCredential = await FirebaseAuth.instance
.signInWithPopup(TwitterAuthProvider());
return userCredential.user != null;
}
Before you can use that, you need to initialize Firebase for the App:
await Firebase.initializeApp();
Don't forget to listen to the user changes, for example:
FirebaseAuth.instance
.authStateChanges()
.listen((User? user) {
if (user == null) {
...
} else {
...
}
});
Also, make sure that you set the callback URL in Twitter's "Authentication settings" to something like:
https://[YOURAPPNAME].firebaseapp.com/__/auth/handler
and that your Firebase Authentications include Twitter as a provider.
you can use the Firebase Auth Plugin provided by the Firebase team.
This plugin support Google, Email and Password, Phone, Anonymously, GitHub, Facebook, and Twitter authentication.
Or you can use Flutter_Twitter package, TwitterAPI package provided by the community.
Hope it will help

In Flutter - How do I push user to a "Thank-you" page in the app after returning from PayPal completed transaction page in web browser

My flutter app requires payments to be made via PayPal in a web browser outside the app. Once the payment is completed the user will be returned to the app and a thank you page should be pushed.
I'm using _launchURL to initiate the web browser from within the app and the following example PayPal url to define the payment.
https://www.paypal.com/cgi-bin/webscr?cmd=_xclick&business=email#domain.com&currency_code=USD&amount=123.99&return=http://example.com&item_name=Document+Studio
Using SystemChannels.lifecycle.setMessageHandler I should be able to test when the app returns from the web browser (AppLifecycleState.resumed). But how do I capture the return URL (http://example.com) or some other value from the web browser to confirm that it has come from the transaction complete page and should be pushed to the apps thank-you page?
Is there a way to pass a value from the browser back to the app?
My other thought was to use Uni_links to "Deep Link" the thank you page within the app and have that as the return url parameter in the PayPal url?
I'm a bit lost with the solution and am only new to flutter, so any advice/guidance would be appreciated.
I am assuming you are using this _launchURL. To do what you desire create a ThankYou class and call it in the following manner. You might want to check resultingValue prior to calling your ThankYou screen. I haven't used the url functionality enough to know what it returns, if anything. It might be null, an int of some sort, such as 404 url not found, perhaps a String?
import 'ThankYou.dart';
_launchURL() async {
const url = 'https://flutter.io';
if (await canLaunch(url)) {
await launch(url).then((resultingValue){
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => ThankYou()));
});
} else {
throw 'Could not launch $url';
}
}