FlutterDriver.Connect Requires VM_SERVICE_URL or String? - flutter

My app is the basic counter, with a FlutterDriver for UI Automation. My conundrum is when I attempt to run my test, it tells me that I need to specify a connection or set the VM_SERVICE_URL
ERROR:
DriverError: Could not determine URL to connect to application. Either
the VM_SERVICE_URL environment variable should be set, or an explicit
URL should be provided to the FlutterDriver.connect() method.
I've tried a few things.
Using FlutterDriver.connect();
Setting the VM_SERVICE_URL in Terminal (MacOS)
Setting the Dart Command Line to include VM_SERVICE_URL with a value
The most success I've had is with the code below. By adding enableFlutterDriverExtension to the lib/main.dart, then executing lib/main.dart, I can copy/paste the ws://127.0.0.1 connection into the test/my_test.dart. This allows me to successfully run my tests, but this isn't an ideal process.
Is there a way to pull in the connection string automatically?
Why does Platform.environment['VM_SERVICE_URL'] always return null despite my having set it?
lib/main.dart
void main() {
enableFlutterDriverExtension();
runApp(const MyApp());
}
test/main_app.dart
void main() {
// enableFlutterDriverExtension();
MainApp.main();
MyTest.main();
}
test/my_test.dart
void main() {
FlutterDriver? driver;
dynamic DartVmServiceUrl;
DartVmServiceUrl ??= Platform.environment['VM_SERVICE_URL'];
print('VM_SERVICE_URL:\t${DartVmServiceUrl}');
String vmServURL = 'ws://127.0.0.1:59488/WK8KTNVXXOo=/ws';
setUpAll( () async {
driver = await FlutterDriver.connect(dartVmServiceUrl: vmServURL);
});
tearDownAll( () {
driver?.close();
});
test('Push Button',() async {
var pushMeButton = find.byValueKey('IncrementButton');
await driver!.tap(pushMeButton);
} );
}

you have to move the files in the specific folders you see below, then try to run from terminal with
flutter drive \
--driver=test/my_test.dart \
--target=test_driver/test_driver.dart
in your lib/main.dart you don't need enableFlutterDriverExtension(); because it is already linked to your main() in the test_driver.dart
also your main in test_driver/test_driver.dart should look like this:
import 'package:{here}/main.dart' as app; // insert here your main app
import 'package:flutter_driver/driver_extension.dart';
void main() {
enableFlutterDriverExtension();
app.main();
}
your my_test.dart should look like this:
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
void main() {
late FlutterDriver driver;
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() {
driver.close();
});
test('check flutter driver health', () async {
Health health = await driver.checkHealth();
print(health.status);
});
}
give attention to use the correct packages to avoid this error.
Error: Not found: 'dart:ui'
import 'dart:ui';

Related

Issue Connecting AWS Amplify to Flutter App

I am trying to connect my AWS amplify data model to my flutter app and have followed all the configuration steps (as per this video: https://www.youtube.com/watch?v=9UjP_TJOY5E&t=642s), however, when I go to run the app in Chrome, I get the following error. error message.
I have imported all the relevant amplify packages:
import 'package:amplify_flutter/amplify_flutter.dart';
import 'package:amplify_datastore/amplify_datastore.dart';
And this is my configuration function:
void _configureAmplify() {
final provider = ModelProvider();
final dataStorePlugin = AmplifyDataStore(modelProvider: provider);
try {
Amplify.addPlugin(dataStorePlugin);
Amplify.configure(amplifyconfig);
debugPrint('Amplify Configured');
} catch (e) {
debugPrint('$e');
}
}
I have also tried running the app on an android emulator, but this does not work either.
Please let me know how I should approach fixing this problem. Thanks!
UPDATE: I also made this video to help you out --> https://www.youtube.com/watch?v=ooCc5wdVyMo
Addition to our discussions on the comment section. I recommend calling the _configureAmplify function from the main function. You can call it like the following:
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await _configureAmplify();
runApp(const AmplifyGroceryListApp());
}
Future<void> _configureAmplify() async {
// Add the following lines to your app initialization to add the DataStore plugin
final datastorePlugin = AmplifyDataStore(modelProvider: ModelProvider.instance);
await Amplify.addPlugin(datastorePlugin);
try {
await Amplify.configure(amplifyconfig);
} on AmplifyAlreadyConfiguredException {
safePrint(
'Tried to reconfigure Amplify; this can occur when your app restarts on Android.');
}
}

getting an error of register adapter in flutter using hive

I have created a simple app for storing data using hive and getx as state management
I have followed all the steps but even thought its showing an error like
After coding when I played ...it worked fine...but when I restart the app...it stops showing white background and an error in console....
have u forgotten register adapter...
I have registered adapter in main...eventhough getting this error
error is
Unhandled Exception: HiveError: Cannot read, unknown typeId: 32. Did you forget to register an adapter?
class TransactionController extends GetxController
{
List<TransactionModel> _transactions=[];
Box<TransactionModel> transactionbox=Hive.box('a');
List<TransactionModel> get transactions{
return _transactions;
}
TransactionController(){
_transactions=[];
for(int x=0;x<transactionbox.values.length;x++)
{
var trns=transactionbox.getAt(x);
if(trns!=null)
_transactions.add(trns);
}
}
int get countlength{
return _transactions.length;
}
void addTransaction(TransactionModel transaction)
{
_transactions.add(transaction);
transactionbox.add(transaction);
update();
}
}
this is model class
import 'package:hive_flutter/hive_flutter.dart';
import 'package:hive/hive.dart';
part 'transactionmodel.g.dart';
#HiveType(typeId: 0)
class TransactionModel
{
#HiveField(0)
String id;
#HiveField(1)
String detail;
#HiveField(2)
bool isExpense;
TransactionModel({
required this.id,
required this.detail,
required this.isExpense,
});
}
this is void main
void main() async
{
WidgetsFlutterBinding.ensureInitialized();
Directory dir=await getApplicationDocumentsDirectory();
await Hive.initFlutter(dir.path);
await Hive.openBox<TransactionModel>('a');
Hive.registerAdapter<TransactionModel>(TransactionModelAdapter());
runApp(MyApp());
}
I see a wrong thing in your code, you're trying to open the Hive box before registering the adapter, you're calling Hive.registerAdapter after you already opened the box, change it with this:
void main() async
{
WidgetsFlutterBinding.ensureInitialized();
Directory dir=await getApplicationDocumentsDirectory();
await Hive.initFlutter(dir.path);
Hive.registerAdapter<TransactionModel>(TransactionModelAdapter()); // this should be first
await Hive.openBox<TransactionModel>('a'); // then this
runApp(MyApp());
}

How to delete local database while uninstalling the flutter windows application?

I am using the DRIFT package (formerly known as MOOR) for local database and I want to delete the database file, when uninstalling the windows application, which is saved in local machine (Windows) as db.sqlite. How can I achieve this?
Drift package for database. Drift documentation. Drift code :
// These imports are only needed to open the database
import 'dart:io';
import 'package:drift/drift.dart';
import 'package:drift/native.dart';
import 'package:path_provider/path_provider.dart';
import 'package:path/path.dart' as path;
import 'package:summa_app/database/program_location/program_location_dao.dart';
import 'package:summa_app/database/program_location/program_location_table.dart';
import 'package:summa_app/database/programs/program_dao.dart';
import 'package:summa_app/database/programs/program_table.dart';
part 'summa_database.g.dart';
#DriftDatabase(tables: [ProgramLocation, DbPrograms], daos: [ProgramLocationDao, ProgramsDao])
class SummaDatabase extends _$SummaDatabase {
// we tell the database where to store the data with this constructor
SummaDatabase() : super(_openConnection());
// you should bump this number whenever you change or add a table definition.
// Migrations are covered later in the documentation.
#override
int get schemaVersion => 1;
#override
Future<void> close() async{
await _openConnection().close();
return super.close();
}
}
LazyDatabase _openConnection() {
// the LazyDatabase util lets us find the right location for the file async.
return LazyDatabase(() async {
// put the database file, called db.sqlite here, into the documents folder
// for your app.
final dbFolder = await getApplicationDocumentsDirectory();
final file = File(path.join(dbFolder.path, 'db.sqlite'));
return NativeDatabase(file);
});
}
There are two options here:
You could close the database, delete the file from the device, and then re-open it.
You can delete everything from all tables, without closing the database:
Future<void> deleteEverything() {
return transaction(() async {
// you only need this if you've manually enabled foreign keys
// await customStatement('PRAGMA foreign_keys = OFF');
for (final table in allTables) {
await delete(table).go();`enter code here`
}
});
}

Process.run() on local machine during Flutter integration test

I write some integration tests for my Flutter application and I need to execute some shell commands on my local machine during testing.
I know that I can execute these commands with Process.run(), but during the integration tests this command is executed on my android phone instead of my local machine.
Is there any way to run a command on my local machine during my integration test?
Somehow with flutter driver it works running processes on your test machine.
In my case it is opening a deep link while running flutter tests. then you get the context.
flutter drive \
--driver=test_driver/driver_tests/your_test.dart \
--target=test_driver/your_driver.dart
your_driver.dart:
import 'package:flutter_driver/driver_extension.dart';
import 'package:arriba/main.dart' as app;
void main() {
enableFlutterDriverExtension();
app.main();
}
your_test.dart:
import 'dart:io';
import 'package:flutter_driver/flutter_driver.dart';
import 'package:test/test.dart';
//!! DOES NOT RUN WITHOUT FLUTTER DRIVER MAIN !!
void main() {
late FlutterDriver driver;
const String shareLink = 'your_link.html';
setUpAll(() async {
driver = await FlutterDriver.connect();
});
tearDownAll(() async {
await driver.close();
});
test(
'starting deep link test',
() async {
driver.waitUntilFirstFrameRasterized();
await Process.run(
'adb',
[
'-d',
'shell',
'am',
'start',
'-a android.intent.action.VIEW',
'-c android.intent.category.BROWSABLE',
'-d $shareLink',
'YOUR PACKAGE NAME',
],
).then((result) {
stdout.write(result.stdout);
stderr.write(result.stderr);
});
},
timeout: const Timeout(Duration(seconds: 60)),
);
}

I get a weird error when trying to initialize Hive

Error: Unhandled Exception: HiveError: You need to initialize Hive or provide a path to store the box.
Essentially I have these in my dependencies so everything should be good.
hive: ^1.4.4+1
hive_flutter: ^0.3.1
path_provider: ^1.6.27
I also have import 'package:hive/hive.dart';
and
import 'package:path_provider/path_provider.dart'; in the file
So I just have
void doSomething() async {
final documentDirectory = await getApplicationDocumentsDirectory();
Hive.init(documentDirectory.path);
}
called.
I do not understand. I think I've done everything correct. Let me know if you need something else.
Hive needs to be initialized when it runs on Android or iOS, therefore you can use a function like this:
Future<Box> openHiveBox(String boxName) async {
if (!kIsWeb && !Hive.isBoxOpen(boxName))
Hive.init((await getApplicationDocumentsDirectory()).path);
return await Hive.openBox(boxName);
}
You'll need to import path_provider in order to access getApplicationDocumentsDirectory()
Try the following code on the main function of your flutter application:
import 'package:path_provider/path_provider.dart';
import 'package:hive/hive.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final appDocumentDirectory = await getApplicationDocumentsDirectory();
Hive.init(appDocumentDirectory.path);
}
Currently, path_provider doesn't support WEB. You can see it here: path_provider.
You have to use another directory for WEB. If you are using BLOC as a state management, you could do something like this:
if (!kIsWeb) {
// if android or tablet
HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: await getApplicationDocumentsDirectory(),
);
} else {
// if web
HydratedBloc.storage = await HydratedStorage.build(
storageDirectory: HydratedStorage.webStorageDirectory,
);
}
I got this error because of a typo:
await Hive.initFlutter;
should've been
await Hive.initFlutter();
I guess you are getting this issue because you are not awaiting the initFlutter.
import 'package:get/get.dart';
import 'package:hive_flutter/hive_flutter.dart';
import 'package:path_provider/path_provider.dart' as path_provider;
Future<void> yourFunction() async {
final dbDir = await path_provider.getApplicationDocumentsDirectory();
// init hive
await Hive.initFlutter(dbDir.path);
await openYourBox();
}
I think you should await your init method.
Actually you don't need use HydratedStorage to initialize Hive on web:
import 'package:hive/src/hive_impl.dart';
import 'package:flutter/foundation.dart';
import 'package:path_provider/path_provider.dart';
initializeHive()async{
//Use HiveImpl() to ensure you don't have conflicting Hive boxes.
HiveInterface _hive = HiveImpl();
if (kIsWeb) {
await _hive.openBox('yourBoxName');
} else {
var dir = await getApplicationDocumentsDirectory();
_hive.init(dir.path);
await _hive.openBox('yourBoxName');
}
}
If you're using Flutter on web, you don't need to initialize Hive and neither provider a path to box, only if you're using it on mobile.