I am trying to setup Flutter Driver tests for my application and the app runs async so I found https://github.com/flutter/flutter/issues/41029 which says all you need to do is add await driver.waitUntilFirstFrameRasterized(); and it should work, while this does stop the test from failing it nos simply does not run.
The app just hangs at the splash screen never even getting into the application itself.
As far as I am understanding, this is all I would need to have setup in order for the test to run
FlutterDriver driver;
// Connect to the Flutter driver before running any tests.
setUpAll(() async {
driver = await FlutterDriver.connect();
await driver.waitUntilFirstFrameRasterized();
// await Directory('screenshots').create();
});
// Close the connection to the driver after the tests have completed.
tearDownAll(() async {
if (driver != null) {
await driver.close();
}
});
However, all I am getting in my terminal is the following output:
VMServiceFlutterDriver: Connecting to Flutter application at http://127.0.0.1:54264/tt9kN4jBSrc=/
VMServiceFlutterDriver: Isolate found with number: 2942164624858163
VMServiceFlutterDriver: Isolate is paused at start.
VMServiceFlutterDriver: Attempting to resume isolate
VMServiceFlutterDriver: Connected to Flutter application.
VMServiceFlutterDriver: waitForCondition message is taking a long time to complete...
I have left it for minutes and nothing happens, I have disabled the firebase initialization in case somehow that is blocking it as I would need to accept the alert dialogue, not that I am even getting that far as I can see.
Turns out I needed to use an IsolatesWorkaround as well
FlutterDriver driver;
IsolatesWorkaround workaround;
// Connect to the Flutter driver before running any tests.
setUpAll(() async {
driver = await FlutterDriver.connect();
workaround = IsolatesWorkaround(driver);
await workaround.resumeIsolates();
await driver.waitUntilFirstFrameRasterized();
if (!await Directory('screenshots').exists()) {
await Directory('screenshots').create();
}
});
// Close the connection to the driver after the tests have completed.
tearDownAll(() async {
await driver?.close();
await workaround.tearDown();
});
See: https://gist.github.com/vishna/03c5d5e8eb14c5e567256782cddce8b4
Related
We have a basic fastapi server with some http and websocket endpoints.
We're using postgres with asyncpg to do some basic CRUD operations.
One example is that there's a post endpoint that creates an item in the DB and notifies the websocket listeners:
async def notify_todo_listeners():
todos = db_handler.fetch_todos()
notify_all(todos)
#app.post("/todo")
async def post_todo(request):
todo = db_handler.insert(request.json())
asyncio.create_task(notify_todo_listeners())
return todo
And we want to test that endpoint in pytest, so we create a temp postgres DB using docker and we also patch the db_handler to be using a mock connection that we create in the test environment.
That connection is setup so that it would be rolled back once the test is finished
#pytest_asyncio.fixture(scope="function")
async def session(monkeypatch):
connection = await asyncpg.connect(CONNECTION_STRING)
transaction = connection.transaction()
await transaction.start()
async def mock_get_connection():
return connection
monkeypatch.setattr(database_handler, "get_connection", mock_get_connection)
yield connection
transaction.rollback()
async def test_post_todo(session):
async with AsyncClient(app=app, base_url="http://test") as client:
response = await client.post(some_todo_object)
assert response.status_code == 200
# some other assertions ...
The problem is when we try to test that endpoint, the part where we create a new task for notifying subscribers and using the DB to fetch the todo list raises this error:
exception=InterfaceError('cannot perform operation: another operation is in progress')
My understanding is that an async connection cannot be used across different co-routines, otherwise we get that error.
Question is, how can we properly mock this database while rolling back all changes made during each test run, while accounting for the possibility of having multiple co-routine tasks running?
I am trying to implement FCM for a flutter web project.
When I run the project in the localhost, it works fine. But when I upload it to firebase hosting (After running flutter build web), I am getting errors.
On the main.dart file, I am trying to get the device token:
final fcmToken = await FirebaseMessaging.instance.getToken(
vapidKey:
"my_key");
However, I am getting this error in the console:
main.dart.js:4430 Uncaught MissingPluginException(No implementation found for method Messaging#getToken on channel plugins.flutter.io/firebase_messaging)
I added the firebase messaging package in my pubspec.yaml file:
firebase_messaging: ^14.2.1
Additionally, I added the service worker code as explained here: https://firebase.flutter.dev/docs/messaging/usage/
Here is my index.html script code:
<script>
window.addEventListener("load", function (ev) {
// Download main.dart.js
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("/firebase-messaging-sw.js");
}
_flutter.loader
.loadEntrypoint({
serviceWorker: {
serviceWorkerVersion: serviceWorkerVersion,
},
})
.then(function (engineInitializer) {
return engineInitializer.initializeEngine();
})
.then(function (appRunner) {
return appRunner.runApp();
});
});
</script>
It looks like a problem with the firebase_messaging package, but I'm using the latest one. Also what I can't understand is why it's working in localhost but not production.
Thoughts anyone?
Running flutter clean solved the problem
I'm using firebase and shared_preference in my flutter project, where I need to store a incoming message to the shared preferences. Whenever a message is received, I am getting the below exception
I/flutter (29300): FlutterFire Messaging: An error occurred in your background messaging handler:
I/flutter (29300): MissingPluginException(No implementation found for method getAll on channel plugins.flutter.io/shared_preferences)
I know that _firebaseMessagingBackgroundHandler will spawn a new isolate, but does that make other plugins unaccessible??
This is my handler
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
final prefs = await SharedPreferences.getInstance();
await prefs.reload();
await prefs.setStringList(
DateTime.now().toIso8601String().substring(0, 19) + ".000000", [message.notification!.body.toString(), message.notification!.title.toString()]);
}
I have also confirmed that shared preferences present in generated_plugin_registrant.dart. I have used FlutterFire CLI for integerating firebase with my app.
I'm the newbie of flutter test driver. I'm trying to run the test and it's failed with some errors in console logs below. I think I need to extend the default timeout for some specific test steps but not sure how to do that. The documentation doesn't mention well about it.
I have one more question: when my app launches, it takes a long time for render, so I want the test wait for the app complete launching and then executing test. How can I do that?
This is console logs when my app just launches:
This is test failed message:
this is my own waitFor()
static Future<void> waitFor(
FlutterDriver driver, SerializableFinder finder) async {
try {
await driver.waitFor(finder, timeout: timeout);
await FlutterDriverUtils.waitForFlutter(driver, timeout: timeout);
} catch (error) {
throw ('Element does not exists => $error');
}}
My app was working normally since today.I already included Firebase Storage in my Android Flutter App and it works after that today I get AppCheck Errors suddenly. I was not include App Check for our project or not enforced in settings. After that I was following the official documentation for initialization appcheck : https://firebase.flutter.dev/docs/app-check/usage.
This is my Kotlin MainActivity:
import android.os.Bundle
import com.google.firebase.FirebaseApp
import com.google.firebase.appcheck.FirebaseAppCheck
import com.google.firebase.appcheck.debug.DebugAppCheckProviderFactory
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
FirebaseApp.initializeApp(/*context=*/ this);
val firebaseAppCheck = FirebaseAppCheck.getInstance()
firebaseAppCheck.installAppCheckProviderFactory(
DebugAppCheckProviderFactory.getInstance())
super.onCreate(savedInstanceState)
}
}
and this is my main():
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
await FirebaseAppCheck.instance.activate();
runApp(MyApp());
}
I also added this to my app/build.gradle
dependencies {
implementation 'com.google.firebase:firebase-appcheck-debug:16.0.0-beta01'
}
When I make a request to firebase storage, I would expect something like this in my console:
D DebugAppCheckProvider: Enter this debug secret into the allow list in the Firebase Console for your project: 123a4567-b89c-12d3-e456-789012345678
Instead, I'm getting an error:
2021-11-21 18:11:51.442 2091-3452/com.sekspir.grind4gain W/ExponenentialBackoff: network unavailable, sleeping.
2021-11-21 18:11:53.500 2091-3452/com.sekspir.grind4gain W/StorageUtil: Error getting App Check token; using placeholder token instead. Error: com.google.firebase.FirebaseException: Error returned from API. code: 403 body: App attestation failed.
2021-11-21 18:12:11.136 2091-3633/com.sekspir.grind4gain V/NativeCrypto: SSL handshake aborted: ssl=0xdaa42da8: I/O error during system call, Connection reset by peer
Did I miss something here? I am using a real Android device with flutter debug build.
This is Firestore AppCheck Stats looks both of request income
But in Storage session there are not any request fail or success.
Can you double check that you correctly enabled the enforcement ?
It is required to work with Firebase Storage solutions.
Are you using your app in "PWA" mode or in "Native" mode ?
The Recaptcha may be mandatory depending on how your app is distributed.
await FirebaseAppCheck.instance.activate(
webRecaptchaSiteKey: 'recaptcha-v3-site-key',
);
I'm not sure about your implementation of the appcheck-debug dependency on the Android Native side.
Since it's already implemented by the Flutter library itself, you should remove it.
Personal note : I had troubles with FirebaseAppCheck on some devices, while it was working perfectly on other devices.
This library is still in beta and I would recommend to wait before using it in production.