From dcb64c74b620a7847fe50f4d237a9837512fbb71 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 22 Aug 2022 22:58:54 +0200 Subject: [PATCH 01/28] test integration is upgrade and working for restore chest --- integration_test/app_test.dart | 116 +++++ .../app_test_integration.dart.disable | 447 ------------------ lib/models/widgets_keys.dart | 3 + lib/screens/common_elements.dart | 1 + lib/screens/home.dart | 1 + lib/screens/myWallets/restore_chest.dart | 2 + lib/screens/myWallets/unlocking_wallet.dart | 7 +- lib/screens/onBoarding/10.dart | 6 +- lib/screens/settings.dart | 2 +- 9 files changed, 134 insertions(+), 451 deletions(-) create mode 100644 integration_test/app_test.dart delete mode 100644 integration_test/app_test_integration.dart.disable create mode 100644 lib/models/widgets_keys.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart new file mode 100644 index 0000000..839881d --- /dev/null +++ b/integration_test/app_test.dart @@ -0,0 +1,116 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:integration_test/integration_test.dart'; + +import 'package:gecko/main.dart' as app; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + group('end-to-end test', () { + testWidgets('Ğecko basics', (tester) async { + app.main(); + // await Future.delayed(const Duration(seconds: 5)); + await tester.pumpAndSettle(const Duration(seconds: 1)); + // await deleteAllWallets(tester); + await restoreChest(tester); + + // Verify the Gecko is well connected. + // await waitFor(tester, 'Vous êtes bien connecté'); + + // Open my chest + await goKey(tester, 'manageWallets', duration: 500); + // await goKey(tester, 'chooseChest'); + + // Enter secret code + await enterText(tester, keyPinForm, 'AAAAA'); + + await tester.pumpAndSettle(); + + // Verify the wallet 3 is here + await waitFor(tester, 'Porteuille 3'); + }); + }); +} + +// Customs actions +Future deleteAllWallets(WidgetTester tester) async { + await goKey(tester, 'drawerMenu'); + await goKey(tester, 'parameters'); + await goKey(tester, 'deleteAllWallets'); + await goKey(tester, 'confirmPopop'); + await tester.pumpAndSettle(); +} + +Future restoreChest(WidgetTester tester) async { + await goKey(tester, 'restoreChest'); + Clipboard.setData(const ClipboardData( + text: + 'smart joy blossom stomach champion fun diary relief gossip hospital logic bike')); + await tester.pumpAndSettle(); + await goKey(tester, 'pasteMnemonic'); + await tester.pumpAndSettle(); + await goKey(tester, 'goNext'); + await goKey(tester, 'goNext'); + await goKey(tester, 'goNext'); + await goKey(tester, 'goNext'); + await goKey(tester, 'cachePassword'); + await enterText(tester, keyPinForm, 'AAAAA'); + await waitFor(tester, 'Accéder à mon coffre'); + await goKey(tester, 'goWalletHome'); + await waitFor(tester, 'ĞD'); + await goBack(tester); + await waitFor(tester, "y'a pas de lézard"); +} + +// CUSTOM METHODES +Future goKey(WidgetTester tester, String buttonKey, + {Finder? customFinder, int duration = 100}) async { + await tester.pumpAndSettle(Duration(milliseconds: duration)); + final Finder finder = customFinder ?? find.byKey(Key(buttonKey)); + await tester.tap(finder); + // await tester.pumpAndSettle(Duration(milliseconds: duration)); +} + +Future goBack(WidgetTester tester) async { + final NavigatorState navigator = tester.state(find.byType(Navigator)); + navigator.pop(); + await tester.pump(); +} + +Future enterText( + WidgetTester tester, GlobalKey fieldKey, String textIn, + [int duration = 200]) async { + await tester.pumpAndSettle(Duration(milliseconds: duration)); + await tester.enterText(find.byKey(fieldKey), textIn); +} + +Future waitFor( + WidgetTester tester, + String text, { + Duration timeout = const Duration(seconds: 5), +}) async { + final end = DateTime.now().add(timeout); + + Finder finder = find.textContaining(text); + + do { + if (DateTime.now().isAfter(end)) { + throw Exception('Timed out waiting for text $text'); + } + + await tester.pumpAndSettle(); + await Future.delayed(const Duration(milliseconds: 100)); + } while (finder.evaluate().isEmpty); +} + +extension Truncate on String { + String truncate({required int max, String suffix = ''}) { + return length < max + ? this + : '${substring(0, substring(0, max - suffix.length).lastIndexOf(" "))}$suffix'; + } +} diff --git a/integration_test/app_test_integration.dart.disable b/integration_test/app_test_integration.dart.disable deleted file mode 100644 index eeec460..0000000 --- a/integration_test/app_test_integration.dart.disable +++ /dev/null @@ -1,447 +0,0 @@ -import 'package:flutter/material.dart'; -import 'dart:io'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:integration_test/integration_test.dart'; - -import 'package:gecko/main.dart' as app; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - int globalTimeout = 2; - group( - 'Gecko end-to-end tests', - () { - // First, define the Finders and use them to locate widgets from the - // test suite. Note: the Strings provided to the `byValueKey` method must - // be the same as the Strings we used for the Keys in step 1. - // final manageWalletsFinder = find.byKey(Key('manageWallets')); - // final buttonFinder = find.byValueKey('increment'); - - // FlutterDriver driver; - WidgetTester tester; - String pinCode; - - // *** Global functions *** // - - // Easy get text - Future getText(String text) async { - Text resultText = tester.firstWidget(find.byKey(Key(text))); - // Text pinCodeText = generatedPinFinder.evaluate().single.widget as Text; - - return resultText.data; - } - - // Function to tap the widget by key - Future tapOn(String key) async { - await tester.tap(find.byKey(Key(key))); - } - - // Function to go back to previous screen - Future goBack() async { - await Process.run( - 'adb', - ['shell', 'input', 'keyevent', 'KEYCODE_BACK'], - runInShell: true, - ); - } - - // Easy sleep - Future sleep(int _time) async { - await Future.delayed(Duration(milliseconds: _time)); - } - - // Test if widget exist on screen, return a boolean - Future isPresent(String text, - {Duration timeout = const Duration(seconds: 1)}) async { - try { - expect(text, findsOneWidget); - return true; - } catch (exception) { - return false; - } - } - - // Create a derivation - Future createDerivation(String _name) async { - await tapOn('addDerivation'); - await sleep(100); - - await tester.enterText(find.byKey(Key('DerivationNameKey')), _name); - - await tapOn('validDerivation'); - await sleep(300); - } - - // Delete a derivation - Future deleteWallet(bool _confirm) async { - await tapOn('deleteWallet'); - await sleep(100); - _confirm - ? await tapOn('confirmDeleting') - : await tapOn('cancelDeleting'); - await sleep(300); - } - - // Delete all wallets - Future deleteAllWallets() async { - await tester.tap(find.byKey(Key('drawerMenu'))); - await sleep(300); - await tester.tap(find.byKey(Key('parameters'))); - await sleep(300); - await tester.tap(find.byKey(Key('deleteAllWallets'))); - await sleep(300); - await tester.tap(find.byKey(Key('confirmDeletingAllWallets'))); - await sleep(300); - } - - // Fast creation of new Keychain - Future createNewKeychain(String name) async { - await tapOn('drawerMenu'); - await sleep(300); - await tapOn('parameters'); - await sleep(300); - await tapOn('generateKeychain'); - expect(find.text(''), findsOneWidget); - - pinCode = await getText('generatedPin'); - - await tapOn('storeKeychain'); - await sleep(100); - await tester.enterText(find.byKey(Key('askedWord')), 'triche'); - await tapOn('walletName'); - await tester.enterText(find.byKey(Key('walletName')), 'name'); - await tapOn('confirmStorage'); - await sleep(300); - return pinCode; - } - - // *** Begin of tests *** // - - testWidgets('OnBoarding - Open wallets management', ( - WidgetTester tester, { - timeout: Timeout.none, - }) async { - app.main(); - await tester.pumpAndSettle(); - - // expect("y'a pas de lézard !", findsOneWidget); - await tester.tap(find.byKey(Key('manageWallets'))); - - print( - '####################################################################'); - - // If a wallet exist, go to delete theme all - await tester.pumpAndSettle(); - if (!await isPresent( - "Je ne connais pour l’instant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.")) { - await tester.pumpAndSettle(); - // await tester.pageBack(); - await goBack(); - - await sleep(500); - await deleteAllWallets(); - - await sleep(300); - await tester.tap(find.byKey(Key('manageWallets'))); - } - - await tester.pumpAndSettle(); - - // Verify onboarding is starting, with text - expect( - "Je ne connais pour l’instant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant.", - findsOneWidget); - }); - - // test('OnBoarding - Go to create restore sentance', ( - // {timeout: Timeout.none}) async { - // await tapOn('goStep1'); - // await tapOn('goStep2'); - // await tapOn('goStep3'); - // await tapOn('goStep4'); - // await tapOn('goStep5'); - // await tapOn('goStep6'); - - // expect( - // "J’ai généré votre phrase de restauration !\nTâchez de la garder bien secrète, car elle permet à quiconque la connaît d’accéder à tous vos portefeuilles.", - // findsOneWidget); - // }); - - // test('OnBoarding - Generate sentance and confirme it', ( - // {timeout: Timeout.none}) async { - // await tapOn('goStep7'); - - // await tester.pumpAndSettle(); - - // Future selectWord() async { - // List words = [for (var i = 1; i <= 13; i += 1) i]; - - // for (var j = 1; j < 13; j++) { - // words[j] = await getText('word$j'); - // } - // expect(await getText('step7'), - // "C'est le moment de noter votre phrase !"); - - // await tapOn('goStep8'); - // await sleep(200); - - // String goodWord = words[int.parse( - // await getText('askedWord'), - // )]; - - // // Enter the expected word - // await tester.enterText(find.byKey(Key('inputWord')), goodWord); - - // // Check if word is valid - // expect(find.text("C'est le bon mot !"), findsOneWidget); - - // // Continue onboarding workflow - // await tapOn('goStep9'); - // } - - // await selectWord(); - - // //Go back 2 times to mnemonic generation screen - // await goBack(); - // await goBack(); - // await sleep(100); - - // // Generate 3 times mnemonic - // await tapOn('generateMnemonic'); - // await tapOn('generateMnemonic'); - // await tapOn('generateMnemonic'); - // await sleep(500); - - // await selectWord(); - // }); - // test('OnBoarding - Generate secret code and confirm it', ( - // {timeout: Timeout.none}) async { - // expect(await getText('step9'), - // "Super !\n\nJe vais maintenant créer votre code secret. \n\nVotre code secret chiffre votre trousseau de clefs, ce qui le rend inutilisable par d’autres, par exemple si vous perdez votre téléphone ou si on vous le vole."); - - // await tapOn('goStep10'); - // await tapOn('goStep11'); - - // while (await getText('generatedPin') == '') { - // print('Waiting for pin code generation...'); - // await sleep(100); - // } - - // // Change secret code 4 times - // for (int i = 0; i < 4; i++) await tapOn('changeSecretCode'); - - // await sleep(500); - // pinCode = await getText('generatedPin'); - - // await tapOn('goStep12'); - // await sleep(300); - - // // //Enter bad secret code - // // await tester.enterText('abcde'); - // // await tapOn('formKey'); - // // await sleep(1500); - // // await tapOn('formKey2'); - - // //Enter good secret code - // await tester.enterText(find.byKey(Key('formKey2')), pinCode); - - // expect(await getText('step13'), - // "Top !\n\nVotre trousseau de clef et votre portefeuille ont été créés avec un immense succès.\n\nFélicitations !"); - // }); - - // test('My wallets - Rename first derivation', ( - // {timeout: const Duration(seconds: 2)}) async { - // await tapOn('goWalletHome'); - - // expect(await getText('myWallets'), "Mes portefeuilles"); - // await sleep(300); - - // // Go to first derivation and rename it - // await tester.tap(find.text('Mon portefeuille courant')); - // await sleep(300); - // await tapOn('renameWallet'); - // await sleep(100); - // await tapOn('walletName'); - // await sleep(100); - // await tester.enterText( - // find.byKey(Key('walletName')), 'Renommage wallet 1'); - // await sleep(300); - // await tapOn('renameWallet'); - // await sleep(400); - // expect('Renommage wallet 1', findsOneWidget); - // await goBack(); - // }); - - // test('My wallets - Create a derivations, open thems, tap all buttons', ( - // {timeout: const Duration(seconds: 2)}) async { - // expect('Renommage wallet 1', findsOneWidget); - - // // Add a second derivation - // await createDerivation('Derivation 2'); - - // // Go to second derivation options - // await tester.tap(find.text('Derivation 2')); - // await sleep(100); - - // // Test options - // await tapOn('displayBalance'); - // await tapOn('displayHistory'); - // await sleep(300); - // await goBack(); - // await tapOn('displayBalance'); - // await sleep(100); - // await tapOn('displayBalance'); - // await sleep(100); - // await tapOn('displayBalance'); - // await tapOn('setDefaultWallet'); - // await sleep(50); - // await tapOn('copyPubkey'); - // expect('Cette clé publique a été copié dans votre presse-papier.', - // findsOneWidget); - // await goBack(); - - // // Add a third derivation - // await createDerivation('Derivation 3'); - - // // Add a fourth derivation - // await createDerivation('Derivation 4'); - // await sleep(50); - - // // Go to third derivation options - // await tester.tap(find.text('Derivation 3')); - // await sleep(100); - // await tapOn('displayBalance'); - - // // Delete third derivation - // await deleteWallet(true); - // }); - - // test('My wallets - Extra tests', ( - // {timeout: const Duration(seconds: 2)}) async { - // // Add derivation 5,6 and 7 - // expect('Derivation 4', findsOneWidget); - // await createDerivation('Derivation 5'); - // await createDerivation('Derivation 6'); - // await createDerivation('Derivation 7'); - - // // Go home and come back to my wallets view - // await goBack(); - // await sleep(100); - // await tapOn('manageWallets'); - // await sleep(200); - // //Enter secret code - // await tester.enterText(find.byKey(Key('formKey')), pinCode); - // await sleep(200); - - // // Go to derivation 6 and delete it - // await tester.tap(find.text('Derivation 6')); - // await sleep(100); - // await deleteWallet(true); - - // // Go to 2nd derivation and check if it's de default - // await tester.tap(find.text('Derivation 2')); - // expect('Ce portefeuille est celui par defaut', findsOneWidget); - // await tapOn('setDefaultWallet'); - // await sleep(100); - // expect('Ce portefeuille est celui par defaut', findsOneWidget); - // await sleep(300); - - // // Display history, copy pubkey, go back and rename wallet name - // await tapOn('displayHistory'); - // await sleep(400); - // await tapOn('copyPubkey'); - // expect('Cette clé publique a été copié dans votre presse-papier.', - // findsOneWidget); - // await sleep(800); - // await goBack(); - // await sleep(300); - // await tapOn('renameWallet'); - // await sleep(100); - // await tapOn('walletName'); - // await sleep(100); - // await tester.enterText( - // find.byKey(Key('walletName')), 'Renommage wallet 2'); - // await sleep(300); - // await tapOn('renameWallet'); - // await sleep(400); - // await goBack(); - // expect('Renommage wallet 2', findsOneWidget); - // await createDerivation('Derivation 8'); - // await createDerivation('Derivation 9'); - // await createDerivation('Derivation 10'); - // await createDerivation('Derivation 11'); - // await createDerivation('Derivation 12'); - // await createDerivation('Derivation 13'); - // await createDerivation('Derivation 14'); - // await createDerivation('Derivation 15'); - // await createDerivation('Derivation 16'); - // await createDerivation('Derivation 17'); - // await createDerivation('Derivation 18'); - // await createDerivation('Derivation 19'); - // await createDerivation('Derivation 20'); - // await sleep(400); - - // // Scroll the wallet screen until Derivation 20 and open it - // await tester.scrollUntilVisible(find.byKey(Key('listWallets')), -300.0); - - // expect('Derivation 20', findsOneWidget); - // await sleep(400); - // await tester.tap(find.text('Derivation 20')); - // await tapOn('copyPubkey'); - // }); - - // test('Search - Search Pi profile, navigate in history transactions', ( - // {timeout: const Duration(seconds: 2)}) async { - // expect('Derivation 20', findsOneWidget); - // await goBack(); - // await goBack(); - // await sleep(200); - // await tapOn('searchIcon'); - // await sleep(400); - // await tester.enterText(find.byKey(Key('searchInput')), - // 'D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'); - // await sleep(100); - // await tapOn('copyPubkey'); - // await sleep(500); - // await tapOn('switchPayHistory'); - // await sleep(1200); - // // await tester.scrollIntoView(find.byValueKey('listTransactions')); - // await tester.scrollUntilVisible( - // find.byKey(Key('listTransactions')), - // -600.0, - // ); - // await sleep(100); - // await tapOn('transaction33'); - // expect('Commentaire:', findsOneWidget); - - // // Want to paste pubkey copied, but doesn't work actualy with flutter driver: https://github.com/flutter/flutter/issues/47448 - // // final ClipboardData pubkeyCopied = - // // await Clipboard.getData(Clipboard.kTextPlain); - // // await tester.enterText(pubkeyCopied.text); - - // await sleep(300); - // }, timeout: Timeout(Duration(minutes: globalTimeout))); - - // test('Wallet generation - Fast wallets generations', ( - // {timeout: const Duration(seconds: 2)}) async { - // expect('Commentaire:', findsOneWidget); - // await goBack(); - // await goBack(); - // await deleteAllWallets(); - // await sleep(100); - // final String pincode = await createNewKeychain('Fast wallet'); - // await sleep(100); - // await tapOn('manageWallets'); - // await sleep(200); - // await tester.enterText(find.byKey(Key('formKey')), pinCode); - // await sleep(100); - // await createDerivation('Derivation 2'); - // await sleep(100); - // await tester.tap(find.text('Fast wallet')); - // expect('Fast wallet', findsOneWidget); - // // Wait 3 seconds at the end - // await sleep(3000); - // }); - }, - ); -} diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart new file mode 100644 index 0000000..c2bbccf --- /dev/null +++ b/lib/models/widgets_keys.dart @@ -0,0 +1,3 @@ +import 'package:flutter/material.dart'; + +final keyPinForm = GlobalKey(); diff --git a/lib/screens/common_elements.dart b/lib/screens/common_elements.dart index 59149f7..1f75f43 100644 --- a/lib/screens/common_elements.dart +++ b/lib/screens/common_elements.dart @@ -62,6 +62,7 @@ class CommonElements { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( + key: const Key('goNext'), style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 4157045..6f093d2 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -581,6 +581,7 @@ Widget welcomeHome(context) { width: 410, height: 70, child: OutlinedButton( + key: const Key('restoreChest'), style: OutlinedButton.styleFrom( side: BorderSide(width: 4, color: orangeC)), onPressed: () { diff --git a/lib/screens/myWallets/restore_chest.dart b/lib/screens/myWallets/restore_chest.dart index 06540a5..c1b9404 100644 --- a/lib/screens/myWallets/restore_chest.dart +++ b/lib/screens/myWallets/restore_chest.dart @@ -91,6 +91,7 @@ class RestoreChest extends StatelessWidget { width: 410, height: 70, child: ElevatedButton( + key: const Key('goNext'), style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background @@ -130,6 +131,7 @@ class RestoreChest extends StatelessWidget { width: 190, height: 60, child: ElevatedButton( + key: const Key('pasteMnemonic'), style: ElevatedButton.styleFrom( elevation: 4, primary: yellowC, // background diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index 7b84eff..2dc1407 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -1,7 +1,9 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; @@ -23,7 +25,6 @@ class UnlockingWallet extends StatelessWidget { // ignore: close_sinks StreamController? errorController; - final formKey = GlobalKey(); Color? pinColor = const Color(0xffF9F9F1); var walletPin = ''; @@ -182,10 +183,11 @@ class UnlockingWallet extends StatelessWidget { } return Form( - key: formKey, + // key: keyPinForm, child: Padding( padding: EdgeInsets.symmetric(vertical: 5 * ratio, horizontal: 30), child: PinCodeTextField( + key: keyPinForm, focusNode: pinFocus, autoFocus: true, appContext: context, @@ -213,6 +215,7 @@ class UnlockingWallet extends StatelessWidget { fieldWidth: 50, activeFillColor: Colors.black, ), + showCursor: kDebugMode ? false : true, cursorColor: Colors.black, animationDuration: const Duration(milliseconds: 300), textStyle: const TextStyle(fontSize: 20, height: 1.6), diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index 2680d33..03643bf 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -2,10 +2,12 @@ import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; @@ -100,6 +102,7 @@ class OnboardingStepTen extends StatelessWidget { Consumer(builder: (context, sub, _) { return sub.nodeConnected ? InkWell( + key: const Key('cachePassword'), onTap: () { walletOptions.changePinCacheChoice(); }, @@ -149,7 +152,7 @@ class OnboardingStepTen extends StatelessWidget { child: Padding( padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 30), child: PinCodeTextField( - key: const Key('formKey2'), + key: keyPinForm, autoFocus: true, appContext: context, pastedTextStyle: TextStyle( @@ -176,6 +179,7 @@ class OnboardingStepTen extends StatelessWidget { fieldWidth: 50, activeFillColor: hasError ? Colors.blueAccent : Colors.black, ), + showCursor: kDebugMode ? false : true, cursorColor: Colors.black, animationDuration: const Duration(milliseconds: 300), textStyle: const TextStyle(fontSize: 20, height: 1.6), diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index b3e8715..5918adc 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -45,7 +45,7 @@ class SettingsScreen extends StatelessWidget { width: buttonWidth, child: Center( child: InkWell( - key: const Key('deleteChest'), + key: const Key('deleteAllWallets'), onTap: () async { log.i('Oublier tous mes coffres'); await _myWallets.deleteAllWallet(context); From cbbd4eee34f255c16c578277a0bff97f8b75041b Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 23 Aug 2022 00:25:16 +0200 Subject: [PATCH 02/28] refactoring: Declare keys for all widgets int widgets_keys.dart --- integration_test/app_test.dart | 101 ++++-------------- integration_test/tests_utility.dart | 55 ++++++++++ lib/models/widgets_keys.dart | 73 ++++++++++++- lib/providers/chest_provider.dart | 5 +- lib/providers/duniter_indexer.dart | 3 +- lib/providers/wallet_options.dart | 11 +- lib/providers/wallets_profiles.dart | 3 +- lib/screens/activity.dart | 5 +- lib/screens/common_elements.dart | 7 +- lib/screens/home.dart | 33 ++---- lib/screens/myWallets/chest_options.dart | 9 +- lib/screens/myWallets/choose_chest.dart | 5 +- lib/screens/myWallets/choose_wallet.dart | 3 +- lib/screens/myWallets/import_g1_v1.dart | 3 +- lib/screens/myWallets/manage_membership.dart | 5 +- lib/screens/myWallets/restore_chest.dart | 7 +- lib/screens/myWallets/show_seed.dart | 3 +- lib/screens/myWallets/unlocking_wallet.dart | 5 +- lib/screens/myWallets/wallet_options.dart | 15 +-- lib/screens/myWallets/wallets_home.dart | 10 +- lib/screens/my_contacts.dart | 3 +- lib/screens/onBoarding/10.dart | 2 +- .../onBoarding/11_congratulations.dart | 3 +- lib/screens/onBoarding/5.dart | 5 +- lib/screens/onBoarding/6.dart | 7 +- lib/screens/onBoarding/9.dart | 5 +- lib/screens/search_result.dart | 3 +- lib/screens/settings.dart | 3 +- lib/screens/wallet_view.dart | 9 +- 29 files changed, 235 insertions(+), 166 deletions(-) create mode 100644 integration_test/tests_utility.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 839881d..b0257be 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -1,5 +1,3 @@ -import 'package:flutter/cupertino.dart'; -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/models/widgets_keys.dart'; @@ -7,110 +5,51 @@ import 'package:integration_test/integration_test.dart'; import 'package:gecko/main.dart' as app; +import 'tests_utility.dart'; + void main() { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('end-to-end test', () { - testWidgets('Ğecko basics', (tester) async { + group('Ğecko basics', () { + testWidgets('Import chests', (tester) async { app.main(); - // await Future.delayed(const Duration(seconds: 5)); await tester.pumpAndSettle(const Duration(seconds: 1)); + // await deleteAllWallets(tester); await restoreChest(tester); - - // Verify the Gecko is well connected. - // await waitFor(tester, 'Vous êtes bien connecté'); - - // Open my chest - await goKey(tester, 'manageWallets', duration: 500); - // await goKey(tester, 'chooseChest'); - - // Enter secret code - await enterText(tester, keyPinForm, 'AAAAA'); - - await tester.pumpAndSettle(); - - // Verify the wallet 3 is here - await waitFor(tester, 'Porteuille 3'); + }); + testWidgets('Send 10 ĞD to ChristCosmic', (tester) async { + // await goKey(tester, buttonKey); }); }); } // Customs actions Future deleteAllWallets(WidgetTester tester) async { - await goKey(tester, 'drawerMenu'); - await goKey(tester, 'parameters'); - await goKey(tester, 'deleteAllWallets'); - await goKey(tester, 'confirmPopop'); + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keyDeleteAllWallets); + await goKey(tester, keyConfirm); await tester.pumpAndSettle(); } Future restoreChest(WidgetTester tester) async { - await goKey(tester, 'restoreChest'); + await goKey(tester, keyRestoreChest); Clipboard.setData(const ClipboardData( text: 'smart joy blossom stomach champion fun diary relief gossip hospital logic bike')); await tester.pumpAndSettle(); - await goKey(tester, 'pasteMnemonic'); + await goKey(tester, keyPastMnemonic); await tester.pumpAndSettle(); - await goKey(tester, 'goNext'); - await goKey(tester, 'goNext'); - await goKey(tester, 'goNext'); - await goKey(tester, 'goNext'); - await goKey(tester, 'cachePassword'); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyCachePassword); await enterText(tester, keyPinForm, 'AAAAA'); await waitFor(tester, 'Accéder à mon coffre'); - await goKey(tester, 'goWalletHome'); + await goKey(tester, keyGoWalletsHome); await waitFor(tester, 'ĞD'); await goBack(tester); await waitFor(tester, "y'a pas de lézard"); } - -// CUSTOM METHODES -Future goKey(WidgetTester tester, String buttonKey, - {Finder? customFinder, int duration = 100}) async { - await tester.pumpAndSettle(Duration(milliseconds: duration)); - final Finder finder = customFinder ?? find.byKey(Key(buttonKey)); - await tester.tap(finder); - // await tester.pumpAndSettle(Duration(milliseconds: duration)); -} - -Future goBack(WidgetTester tester) async { - final NavigatorState navigator = tester.state(find.byType(Navigator)); - navigator.pop(); - await tester.pump(); -} - -Future enterText( - WidgetTester tester, GlobalKey fieldKey, String textIn, - [int duration = 200]) async { - await tester.pumpAndSettle(Duration(milliseconds: duration)); - await tester.enterText(find.byKey(fieldKey), textIn); -} - -Future waitFor( - WidgetTester tester, - String text, { - Duration timeout = const Duration(seconds: 5), -}) async { - final end = DateTime.now().add(timeout); - - Finder finder = find.textContaining(text); - - do { - if (DateTime.now().isAfter(end)) { - throw Exception('Timed out waiting for text $text'); - } - - await tester.pumpAndSettle(); - await Future.delayed(const Duration(milliseconds: 100)); - } while (finder.evaluate().isEmpty); -} - -extension Truncate on String { - String truncate({required int max, String suffix = ''}) { - return length < max - ? this - : '${substring(0, substring(0, max - suffix.length).lastIndexOf(" "))}$suffix'; - } -} diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart new file mode 100644 index 0000000..30bd14d --- /dev/null +++ b/integration_test/tests_utility.dart @@ -0,0 +1,55 @@ +// CUSTOM METHODES +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; + +Future goKey(WidgetTester tester, Key buttonKey, + {Finder? customFinder, int duration = 100}) async { + await tester.pumpAndSettle(Duration(milliseconds: duration)); + final Finder finder = customFinder ?? find.byKey(buttonKey); + log.d('INTEGRATION TEST: Tap on ${finder.description}}'); + await tester.tap(finder); + // await tester.pumpAndSettle(Duration(milliseconds: duration)); +} + +Future goBack(WidgetTester tester) async { + final NavigatorState navigator = tester.state(find.byType(Navigator)); + log.d('INTEGRATION TEST: Go back'); + navigator.pop(); + await tester.pump(); +} + +Future enterText(WidgetTester tester, Key fieldKey, String textIn, + [int duration = 200]) async { + await tester.pumpAndSettle(Duration(milliseconds: duration)); + log.d('INTEGRATION TEST: Enter text: $textIn'); + await tester.enterText(find.byKey(fieldKey), textIn); +} + +Future waitFor( + WidgetTester tester, + String text, { + Duration timeout = const Duration(seconds: 5), +}) async { + final end = DateTime.now().add(timeout); + + Finder finder = find.textContaining(text); + log.d('INTEGRATION TEST: Wait for: $text'); + + do { + if (DateTime.now().isAfter(end)) { + throw Exception('Timed out waiting for text $text'); + } + + await tester.pumpAndSettle(); + await Future.delayed(const Duration(milliseconds: 100)); + } while (finder.evaluate().isEmpty); +} + +extension Truncate on String { + String truncate({required int max, String suffix = ''}) { + return length < max + ? this + : '${substring(0, substring(0, max - suffix.length).lastIndexOf(" "))}$suffix'; + } +} diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index c2bbccf..e83e29d 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -1,3 +1,74 @@ import 'package:flutter/material.dart'; -final keyPinForm = GlobalKey(); +// General +const keyInfoPopup = Key('keyInfoPopup'); +const keyGoNext = Key('keyGoNext'); +const keyCancel = Key('keyCancel'); +const keyConfirm = Key('keyConfirm'); + +// Home +const keyParameters = Key('keyParameters'); +const keyContacts = Key('keyContacts'); +const keyDrawerMenu = Key('keyDrawerMenu'); +const keyManageWallets = Key('keyManageWallets'); +const keyRestoreChest = Key('keyRestoreChest'); + +// Wallets home +const keyImportG1v1 = Key('keyImportG1v1'); +const keyChangeChest = Key('keyChangeChest'); +const keyListWallets = Key('keyListWallets'); +const keyAddDerivation = Key('keyAddDerivation'); + +// Wallet options +const keyCopyAddress = Key('keyCopyAddress'); +const keyOpenActivity = Key('keyOpenActivity'); +const keyManageMembership = Key('keyManageMembership'); +const keySetDefaultWallet = Key('keySetDefaultWallet'); +const keyDeleteWallet = Key('keyDeleteWallet'); +const keyWalletName = Key('keyWalletName'); +const keyRenameWallet = Key('keyRenameWallet'); + +// Chest options +const keyShowSeed = Key('keyShowSeed'); +const keyChangePin = Key('keyChangePin'); +const keycreateRootDerivation = Key('keycreateRootDerivation'); +const keyDeleteChest = Key('keyDeleteChest'); + +// Manage membership +const keyMigrateIdentity = Key('keyMigrateIdentity'); +const keyRevokeIdty = Key('keyRevokeIdty'); + +// Choose chest +const keyCreateNewChest = Key('keyCreateNewChest'); +const keyImportChest = Key('keyImportChest'); + +// Profile view +const keyViewActivity = Key('keyViewActivity'); +const keyCertify = Key('keyCertify'); +const keyPay = Key('keyPay'); + +// Activity view +const keyListTransactions = Key('keyListTransactions'); + +// Unlock wallet +const keyPinForm = Key('keyPinForm'); +const keyPopButton = Key('keyPopButton'); +const keyCachePassword = Key('keyCachePassword'); + +// Settings +const keyDeleteAllWallets = Key('keyDeleteAllWallets'); + +// Onboarding +const keyPastMnemonic = Key('keyPastMnemonic'); +const keyBubbleSpeak = Key('keyBubbleSpeak'); +const keyGenerateMnemonic = Key('keyGenerateMnemonic'); +const keyAskedWord = Key('keyAskedWord'); +const keyInputWord = Key('keyInputWord'); +const keyGeneratedPin = Key('keyGeneratedPin'); +const keyGoWalletsHome = Key('keyGoWalletsHome'); + +// Unit keys +Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); +Key keyIndexerResult(int keyId) => Key('keyIndexerResult$keyId'); +Key keyTransaction(int keyId) => Key('keyTransaction$keyId'); +Key keySearchResult(int keyId) => Key('keySearchResult$keyId'); diff --git a/lib/providers/chest_provider.dart b/lib/providers/chest_provider.dart index 0134e26..ce788b9 100644 --- a/lib/providers/chest_provider.dart +++ b/lib/providers/chest_provider.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; @@ -59,13 +60,13 @@ class ChestProvider with ChangeNotifier { title: Text('areYouSureToDeleteWallet'.tr(args: [walletName!])), actions: [ TextButton( - child: Text("no".tr(), key: const Key('cancelDeleting')), + child: Text("no".tr(), key: keyCancel), onPressed: () { Navigator.pop(context, false); }, ), TextButton( - child: Text("yes".tr(), key: const Key('confirmDeleting')), + child: Text("yes".tr(), key: keyConfirm), onPressed: () { Navigator.pop(context, true); }, diff --git a/lib/providers/duniter_indexer.dart b/lib/providers/duniter_indexer.dart index 65a96c3..a4570fb 100644 --- a/lib/providers/duniter_indexer.dart +++ b/lib/providers/duniter_indexer.dart @@ -8,6 +8,7 @@ import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/queries_indexer.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; @@ -301,7 +302,7 @@ class DuniterIndexer with ChangeNotifier { Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: Key('searchResult${keyID++}'), + key: keyIndexerResult(keyID++), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider.defaultAvatar(avatarSize), diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index c1a2821..1fcac90 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'dart:async'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; @@ -258,7 +259,7 @@ class WalletOptionsProvider with ChangeNotifier { Consumer( builder: (context, wOptions, _) { return TextButton( - key: const Key('infoPopup'), + key: keyInfoPopup, child: Text( "validate".tr(), style: TextStyle( @@ -354,7 +355,7 @@ class WalletOptionsProvider with ChangeNotifier { Consumer( builder: (context, wOptions, _) { return TextButton( - key: const Key('infoPopup'), + key: keyInfoPopup, child: Text( "validate".tr(), style: TextStyle( @@ -381,7 +382,7 @@ class WalletOptionsProvider with ChangeNotifier { mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( - key: const Key('cancel'), + key: keyCancel, child: Text( "cancel".tr(), style: TextStyle( @@ -457,7 +458,7 @@ class WalletOptionsProvider with ChangeNotifier { width: 260, child: Stack(children: [ TextField( - key: const Key('walletName'), + key: keyWalletName, autofocus: false, focusNode: walletNameFocus, enabled: isEditing, @@ -481,7 +482,7 @@ class WalletOptionsProvider with ChangeNotifier { Positioned( right: 0, child: InkWell( - key: const Key('renameWallet'), + key: keyRenameWallet, onTap: () async { // _isNewNameValid = // walletProvider.editWalletName(wallet.id(), isCesium: false); diff --git a/lib/providers/wallets_profiles.dart b/lib/providers/wallets_profiles.dart index ce181c5..3dba88a 100644 --- a/lib/providers/wallets_profiles.dart +++ b/lib/providers/wallets_profiles.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; @@ -166,7 +167,7 @@ class WalletsProfilesProvider with ChangeNotifier { ), Row(children: [ GestureDetector( - key: const Key('copyPubkey'), + key: keyCopyAddress, onTap: () { Clipboard.setData(ClipboardData(text: address)); snackCopyKey(context); diff --git a/lib/screens/activity.dart b/lib/screens/activity.dart index ebb0aed..5635c49 100644 --- a/lib/screens/activity.dart +++ b/lib/screens/activity.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/queries_indexer.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/home.dart'; @@ -132,7 +133,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { child: Builder( builder: (context) => Expanded( child: ListView( - key: const Key('listTransactions'), + key: keyListTransactions, controller: scrollController, children: [historyView(context, result)], ), @@ -286,7 +287,7 @@ class ActivityScreen extends StatelessWidget with ChangeNotifier { child: // Row(children: [Column(children: [],)],) ListTile( - key: Key('transaction${keyID++}'), + key: keyTransaction(keyID++), contentPadding: const EdgeInsets.only( left: 20, right: 30, top: 15, bottom: 15), leading: ClipOval( diff --git a/lib/screens/common_elements.dart b/lib/screens/common_elements.dart index 1f75f43..d077384 100644 --- a/lib/screens/common_elements.dart +++ b/lib/screens/common_elements.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter_markdown/flutter_markdown.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; @@ -62,7 +63,7 @@ class CommonElements { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( - key: const Key('goNext'), + key: keyGoNext, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background @@ -248,7 +249,7 @@ Future confirmPopup(BuildContext context, String title) async { mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( - key: const Key('confirmPopop'), + key: keyConfirm, child: Text( "yes".tr(), style: const TextStyle( @@ -296,7 +297,7 @@ Future infoPopup(BuildContext context, String title) async { mainAxisAlignment: MainAxisAlignment.center, children: [ TextButton( - key: const Key('infoPopup'), + key: keyInfoPopup, child: const Text( "D'accord", style: TextStyle( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 6f093d2..ddff84c 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -5,6 +5,7 @@ import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:easy_localization/easy_localization.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/stateful_wrapper.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/home.dart'; @@ -64,7 +65,7 @@ class HomeScreen extends StatelessWidget { ]), ), ListTile( - key: const Key('parameters'), + key: keyParameters, title: Text('parameters'.tr()), onTap: () { Navigator.pop(context); @@ -77,7 +78,7 @@ class HomeScreen extends StatelessWidget { }, ), ListTile( - key: const Key('contacts'), + key: keyContacts, title: Text('contactsManagement'.tr()), onTap: () { Navigator.pop(context); @@ -89,26 +90,6 @@ class HomeScreen extends StatelessWidget { ); }, ), - - // ListTile( - // key: const Key('substrateSandbox'), - // title: const Text('Substrate debug'), - // onTap: () { - // Navigator.pop(context); - // Navigator.push( - // context, - // MaterialPageRoute(builder: (context) { - // return const SubstrateSandBox(); - // }), - // ); - // }, - // ), - - // ListTile( - // title: const Text('A propos'), - // onTap: () { - // }, - // ), ])), Align( alignment: FractionalOffset.bottomCenter, @@ -220,7 +201,7 @@ Widget geckHome(context) { left: 15, child: Builder( builder: (context) => IconButton( - key: const Key('drawerMenu'), + key: keyDrawerMenu, icon: const Icon( Icons.menu, color: Colors.white, @@ -343,7 +324,7 @@ Widget geckHome(context) { ], ), child: ClipOval( - key: const Key('manageWallets'), + key: keyManageWallets, child: Material( color: orangeC, // button color child: InkWell( @@ -466,7 +447,7 @@ Widget welcomeHome(context) { left: 15, child: Builder( builder: (context) => IconButton( - key: const Key('drawerMenu'), + key: keyDrawerMenu, icon: const Icon( Icons.menu, color: Colors.white, @@ -581,7 +562,7 @@ Widget welcomeHome(context) { width: 410, height: 70, child: OutlinedButton( - key: const Key('restoreChest'), + key: keyRestoreChest, style: OutlinedButton.styleFrom( side: BorderSide(width: 4, color: orangeC)), onPressed: () { diff --git a/lib/screens/myWallets/chest_options.dart b/lib/screens/myWallets/chest_options.dart index 221aeda..7b5e59c 100644 --- a/lib/screens/myWallets/chest_options.dart +++ b/lib/screens/myWallets/chest_options.dart @@ -6,6 +6,7 @@ import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:flutter/services.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/chest_provider.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -58,7 +59,7 @@ class ChestOptions extends StatelessWidget { child: Column(children: [ SizedBox(height: 30 * ratio), InkWell( - key: const Key('showSeed'), + key: keyShowSeed, onTap: () async { MyWalletsProvider myWalletProvider = Provider.of(context, listen: false); @@ -108,7 +109,7 @@ class ChestOptions extends StatelessWidget { SizedBox(height: 10 * ratio), Consumer(builder: (context, sub, _) { return InkWell( - key: const Key('changePin'), + key: keyChangePin, onTap: sub.nodeConnected ? () async { // await _chestProvider.changePin(context, cesiumWallet); @@ -152,7 +153,7 @@ class ChestOptions extends StatelessWidget { SizedBox(height: 10 * ratio), Consumer(builder: (context, sub, _) { return InkWell( - key: const Key('createRootDerivation'), + key: keycreateRootDerivation, onTap: sub.nodeConnected ? () async { await Navigator.push( @@ -188,7 +189,7 @@ class ChestOptions extends StatelessWidget { }), SizedBox(height: 10 * ratio), InkWell( - key: const Key('deleteChest'), + key: keyDeleteChest, onTap: () async { await chestProvider.deleteChest(context, currentChest); }, diff --git a/lib/screens/myWallets/choose_chest.dart b/lib/screens/myWallets/choose_chest.dart index a3d4bf9..4974f2c 100644 --- a/lib/screens/myWallets/choose_chest.dart +++ b/lib/screens/myWallets/choose_chest.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/models/wallet_data.dart'; import 'package:flutter/material.dart'; @@ -156,7 +157,7 @@ class _ChooseChestState extends State { child: Align( alignment: Alignment.bottomCenter, child: InkWell( - key: const Key('createNewChest'), + key: keyCreateNewChest, onTap: () { Navigator.push( context, @@ -179,7 +180,7 @@ class _ChooseChestState extends State { ), ), InkWell( - key: const Key('importChest'), + key: keyImportChest, onTap: () { Navigator.push( context, diff --git a/lib/screens/myWallets/choose_wallet.dart b/lib/screens/myWallets/choose_wallet.dart index e4823a8..eb38197 100644 --- a/lib/screens/myWallets/choose_wallet.dart +++ b/lib/screens/myWallets/choose_wallet.dart @@ -7,6 +7,7 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; @@ -112,7 +113,7 @@ class ChooseWalletScreen extends StatelessWidget { return CustomScrollView(slivers: [ const SliverToBoxAdapter(child: SizedBox(height: 20)), SliverGrid.count( - key: const Key('listWallets'), + key: keyListWallets, crossAxisCount: nTule, childAspectRatio: 1, crossAxisSpacing: 0, diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index 6448c8b..5b8b332 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -7,6 +7,7 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallet_options.dart'; @@ -173,7 +174,7 @@ class ImportG1v1 extends StatelessWidget { ), const SizedBox(height: 20), GestureDetector( - key: const Key('copyPubkey'), + key: keyCopyAddress, onTap: () { Clipboard.setData( ClipboardData(text: sub.g1V1NewAddress)); diff --git a/lib/screens/myWallets/manage_membership.dart b/lib/screens/myWallets/manage_membership.dart index 4a05ec0..99feb0b 100644 --- a/lib/screens/myWallets/manage_membership.dart +++ b/lib/screens/myWallets/manage_membership.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/screens/myWallets/migrate_identity.dart'; // import 'package:gecko/models/wallet_data.dart'; // import 'package:gecko/providers/my_wallets.dart'; @@ -41,7 +42,7 @@ class ManageMembership extends StatelessWidget { Widget migrateIdentity(BuildContext context) { return InkWell( - key: const Key('migrateIdentity'), + key: keyMigrateIdentity, onTap: () async { Navigator.push( context, @@ -64,7 +65,7 @@ class ManageMembership extends StatelessWidget { Widget revokeMyIdentity(BuildContext context) { return InkWell( - key: const Key('revokeIdty'), + key: keyRevokeIdty, onTap: () async { // TODOO: Generate revoke document, and understand extrinsic identity.revokeIdentity options // final _answer = await confirmPopup(context, diff --git a/lib/screens/myWallets/restore_chest.dart b/lib/screens/myWallets/restore_chest.dart index c1b9404..4ec6d68 100644 --- a/lib/screens/myWallets/restore_chest.dart +++ b/lib/screens/myWallets/restore_chest.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/common_elements.dart'; @@ -91,7 +92,7 @@ class RestoreChest extends StatelessWidget { width: 410, height: 70, child: ElevatedButton( - key: const Key('goNext'), + key: keyGoNext, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background @@ -131,7 +132,7 @@ class RestoreChest extends StatelessWidget { width: 190, height: 60, child: ElevatedButton( - key: const Key('pasteMnemonic'), + key: keyPastMnemonic, style: ElevatedButton.styleFrom( elevation: 4, primary: yellowC, // background @@ -175,7 +176,7 @@ class RestoreChest extends StatelessWidget { color: Colors.white, child: Text( text, - key: const Key('importText'), + key: keyBubbleSpeak, textAlign: TextAlign.justify, style: const TextStyle( color: Colors.black, fontSize: 19, fontWeight: FontWeight.w400), diff --git a/lib/screens/myWallets/show_seed.dart b/lib/screens/myWallets/show_seed.dart index b30b463..002bed1 100644 --- a/lib/screens/myWallets/show_seed.dart +++ b/lib/screens/myWallets/show_seed.dart @@ -4,6 +4,7 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/common_elements.dart'; @@ -206,7 +207,7 @@ class ShowSeed extends StatelessWidget { ), Text( dataWord, - key: Key('word$dataWord'), + key: keyMnemonicWord(dataWord), style: TextStyle(fontSize: 17 * ratio, color: Colors.black), ), ]), diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index 2dc1407..3011588 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -53,7 +53,7 @@ class UnlockingWallet extends StatelessWidget { left: 15, child: Builder( builder: (context) => IconButton( - key: const Key('popButton'), + key: keyPopButton, icon: const Icon( Icons.arrow_back, color: Colors.black, @@ -104,6 +104,7 @@ class UnlockingWallet extends StatelessWidget { SizedBox(height: 3 * ratio), if (canUnlock) InkWell( + key: keyCachePassword, onTap: () { walletOptions.changePinCacheChoice(); }, @@ -128,7 +129,7 @@ class UnlockingWallet extends StatelessWidget { const SizedBox(height: 10), // if (canUnlock) InkWell( - key: const Key('chooseChest'), + key: keyChangeChest, onTap: () { Navigator.push( context, diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index 58f58ee..a202abd 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -213,7 +214,7 @@ class WalletOptions extends StatelessWidget { else const SizedBox(), if (isMember.data!) - manageMemberStatus(context) + manageMembership(context) ]); }), ]); @@ -334,7 +335,7 @@ class WalletOptions extends StatelessWidget { Widget pubkeyWidget(WalletOptionsProvider walletProvider, BuildContext ctx) { final String shortPubkey = getShortPubkey(walletProvider.address.text); return GestureDetector( - key: const Key('copyPubkey'), + key: keyCopyAddress, onTap: () { Clipboard.setData(ClipboardData(text: walletProvider.address.text)); snackCopyKey(ctx); @@ -394,7 +395,7 @@ class WalletOptions extends StatelessWidget { WalletsProfilesProvider historyProvider, WalletOptionsProvider walletProvider) { return InkWell( - key: const Key('displayActivity'), + key: keyOpenActivity, onTap: () { // _historyProvider.nPage = 1; Navigator.push( @@ -431,11 +432,11 @@ class WalletOptions extends StatelessWidget { ); } - Widget manageMemberStatus(BuildContext context) { + Widget manageMembership(BuildContext context) { WalletOptionsProvider walletOptions = Provider.of(context, listen: false); return InkWell( - key: const Key('manageStatus'), + key: keyManageMembership, onTap: () { Navigator.push( context, @@ -471,7 +472,7 @@ class WalletOptions extends StatelessWidget { WalletData defaultWallet = myWalletProvider.getDefaultWallet(); walletOptions.isDefaultWallet = (defaultWallet.number == wallet.id()[1]); return InkWell( - key: const Key('setDefaultWallet'), + key: keySetDefaultWallet, onTap: !walletProvider.isDefaultWallet ? () async { await setDefaultWallet(context, currentChest); @@ -544,7 +545,7 @@ class WalletOptions extends StatelessWidget { !hasConsumers.data! && (balance > 2 || balance == 0); return InkWell( - key: const Key('deleteWallet'), + key: keyDeleteWallet, onTap: canDelete ? () async { await walletProvider.deleteWallet(context, wallet); diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index 19a324c..03ba5e1 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/my_wallets.dart'; @@ -59,7 +60,6 @@ class WalletsHome extends StatelessWidget { ); }), title: Text(currentChest.name!, - key: const Key('myWallets'), style: TextStyle(color: Colors.grey[850])), backgroundColor: const Color(0xffFFD58D), ), @@ -108,7 +108,7 @@ class WalletsHome extends StatelessWidget { )), const SizedBox(height: 30), InkWell( - key: const Key('importG1v1'), + key: keyImportG1v1, onTap: () { Navigator.push( context, @@ -130,7 +130,7 @@ class WalletsHome extends StatelessWidget { ), const SizedBox(height: 5), InkWell( - key: const Key('changeChest'), + key: keyChangeChest, onTap: () { Navigator.push( context, @@ -190,7 +190,7 @@ class WalletsHome extends StatelessWidget { return CustomScrollView(slivers: [ const SliverToBoxAdapter(child: SizedBox(height: 20)), SliverGrid.count( - key: const Key('listWallets'), + key: keyListWallets, crossAxisCount: nTule, childAspectRatio: 1, crossAxisSpacing: 0, @@ -366,7 +366,7 @@ class WalletsHome extends StatelessWidget { child: Column(children: [ Expanded( child: InkWell( - key: const Key('addDerivation'), + key: keyAddDerivation, onTap: () async { if (!myWalletProvider.isNewDerivationLoading) { WalletData? defaultWallet = diff --git a/lib/screens/my_contacts.dart b/lib/screens/my_contacts.dart index 31ab42c..abe9fc0 100644 --- a/lib/screens/my_contacts.dart +++ b/lib/screens/my_contacts.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/providers/duniter_indexer.dart'; @@ -71,7 +72,7 @@ class ContactsScreen extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: Key('searchResult${keyID++}'), + key: keySearchResult(keyID++), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index 03643bf..82df70c 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -102,7 +102,7 @@ class OnboardingStepTen extends StatelessWidget { Consumer(builder: (context, sub, _) { return sub.nodeConnected ? InkWell( - key: const Key('cachePassword'), + key: keyCachePassword, onTap: () { walletOptions.changePinCacheChoice(); }, diff --git a/lib/screens/onBoarding/11_congratulations.dart b/lib/screens/onBoarding/11_congratulations.dart index c461a3b..11f6b29 100644 --- a/lib/screens/onBoarding/11_congratulations.dart +++ b/lib/screens/onBoarding/11_congratulations.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/myWallets/wallets_home.dart'; @@ -54,7 +55,7 @@ Widget finishButton(BuildContext context) { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( - key: const Key('goWalletHome'), + key: keyGoWalletsHome, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, diff --git a/lib/screens/onBoarding/5.dart b/lib/screens/onBoarding/5.dart index 6b9426f..55e2466 100644 --- a/lib/screens/onBoarding/5.dart +++ b/lib/screens/onBoarding/5.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/screens/common_elements.dart'; @@ -80,7 +81,7 @@ class _ChooseChestState extends State { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( - key: const Key('generateMnemonic'), + key: keyGenerateMnemonic, style: ElevatedButton.styleFrom( elevation: 4, primary: const Color(0xffFFD58D), @@ -174,7 +175,7 @@ Widget arrayCell(dataWord) { ), Text( dataWord.split(':')[1], - key: Key('word${dataWord.split(':')[0]}'), + key: keyMnemonicWord(dataWord.split(':')[0]), style: TextStyle(fontSize: 17 * ratio, color: Colors.black), ), ]), diff --git a/lib/screens/onBoarding/6.dart b/lib/screens/onBoarding/6.dart index 5a58006..309ae29 100644 --- a/lib/screens/onBoarding/6.dart +++ b/lib/screens/onBoarding/6.dart @@ -4,6 +4,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/onBoarding/7.dart'; @@ -66,7 +67,7 @@ class OnboardingStepSix extends StatelessWidget { true), SizedBox(height: isTall ? 70 : 20), Text('${generateWalletProvider.nbrWord + 1}', - key: const Key('askedWord'), + key: keyAskedWord, style: TextStyle( fontSize: isTall ? 17 : 15, color: orangeC, @@ -81,7 +82,7 @@ class OnboardingStepSix extends StatelessWidget { )), width: 430, child: TextFormField( - key: const Key('inputWord'), + key: keyInputWord, autofocus: true, enabled: !generateWalletProvider.isAskedWordValid, controller: wordController, @@ -206,7 +207,7 @@ Widget arrayCell(dataWord) { ), Text( dataWord.split(':')[1], - key: Key('word${dataWord.split(':')[0]}'), + key: keyMnemonicWord(dataWord.split(':')[0]), style: const TextStyle(fontSize: 20, color: Colors.black), ), ]), diff --git a/lib/screens/onBoarding/9.dart b/lib/screens/onBoarding/9.dart index ed29fce..a2b83ea 100644 --- a/lib/screens/onBoarding/9.dart +++ b/lib/screens/onBoarding/9.dart @@ -3,6 +3,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/generate_wallets.dart'; import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/onBoarding/10.dart'; @@ -52,7 +53,7 @@ class OnboardingStepNine extends StatelessWidget { alignment: Alignment.centerRight, children: [ TextField( - key: const Key('generatedPin'), + key: keyGeneratedPin, enabled: false, controller: generateWalletProvider.pin, maxLines: 1, @@ -79,7 +80,7 @@ class OnboardingStepNine extends StatelessWidget { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( - key: const Key('changeSecretCode'), + key: keyChangePin, style: ElevatedButton.styleFrom( elevation: 4, primary: const Color(0xffFFD58D), diff --git a/lib/screens/search_result.dart b/lib/screens/search_result.dart index a563873..89ccc05 100644 --- a/lib/screens/search_result.dart +++ b/lib/screens/search_result.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/providers/duniter_indexer.dart'; @@ -94,7 +95,7 @@ class SearchResultScreen extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: Key('searchResult${keyID++}'), + key: keySearchResult(keyID++), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 5918adc..f219eea 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -1,6 +1,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/duniter_indexer.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/settings_provider.dart'; @@ -45,7 +46,7 @@ class SettingsScreen extends StatelessWidget { width: buttonWidth, child: Center( child: InkWell( - key: const Key('deleteAllWallets'), + key: keyDeleteAllWallets, onTap: () async { log.i('Oublier tous mes coffres'); await _myWallets.deleteAllWallet(context); diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index bbe47d7..c606cc9 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -5,6 +5,7 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; import 'package:gecko/models/g1_wallets_list.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/substrate_sdk.dart'; @@ -116,7 +117,7 @@ class WalletViewScreen extends StatelessWidget { child: Material( color: yellowC, //const Color(0xffFFD58D), // button color child: InkWell( - key: const Key('viewHistory'), + key: keyViewActivity, splashColor: orangeC, // inkwell color child: const Padding( padding: EdgeInsets.all(13), @@ -206,7 +207,7 @@ class WalletViewScreen extends StatelessWidget { color: const Color(0xffFFD58D), // button color child: InkWell( - key: const Key('certify'), + key: keyCertify, splashColor: orangeC, // inkwell color child: const Padding( padding: EdgeInsets.only(bottom: 0), @@ -290,7 +291,7 @@ class WalletViewScreen extends StatelessWidget { child: Material( color: const Color(0xffFFD58D), // button color child: InkWell( - key: const Key('copyKey'), + key: keyCopyAddress, splashColor: orangeC, // inkwell color child: const Padding( padding: EdgeInsets.all(20), @@ -331,7 +332,7 @@ class WalletViewScreen extends StatelessWidget { child: Material( color: orangeC, // button color child: InkWell( - key: const Key('pay'), + key: keyPay, splashColor: yellowC, onTap: sub.nodeConnected ? () { From fc80f5693c7715807780a8da22c6b1d419554e2e Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 23 Aug 2022 02:13:54 +0200 Subject: [PATCH 03/28] test: execute a transaction to ChristCosmic --- integration_test/app_test.dart | 47 ++++++++++++++++++------ integration_test/tests_utility.dart | 20 ++++++++++ lib/models/widgets_keys.dart | 14 +++++-- lib/providers/duniter_indexer.dart | 3 +- lib/screens/home.dart | 3 +- lib/screens/my_contacts.dart | 3 +- lib/screens/search.dart | 3 ++ lib/screens/search_result.dart | 3 +- lib/screens/transaction_in_progress.dart | 2 + lib/screens/wallet_view.dart | 2 + 10 files changed, 78 insertions(+), 22 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index b0257be..a30b1e0 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -1,10 +1,9 @@ +import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; - import 'package:gecko/main.dart' as app; - import 'tests_utility.dart'; void main() { @@ -15,22 +14,27 @@ void main() { app.main(); await tester.pumpAndSettle(const Duration(seconds: 1)); - // await deleteAllWallets(tester); + // Delete all existing chests + await deleteAllWallets(tester); + + // Restore a chest await restoreChest(tester); - }); - testWidgets('Send 10 ĞD to ChristCosmic', (tester) async { - // await goKey(tester, buttonKey); + + // Execute a transaction to ChristCosmic + await payChrist(tester); }); }); } // Customs actions Future deleteAllWallets(WidgetTester tester) async { - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keyDeleteAllWallets); - await goKey(tester, keyConfirm); - await tester.pumpAndSettle(); + if (await isPresent(tester, 'Rechercher')) { + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keyDeleteAllWallets); + await goKey(tester, keyConfirm); + await tester.pumpAndSettle(); + } } Future restoreChest(WidgetTester tester) async { @@ -45,7 +49,8 @@ Future restoreChest(WidgetTester tester) async { await goKey(tester, keyGoNext); await goKey(tester, keyGoNext); await goKey(tester, keyGoNext); - await goKey(tester, keyCachePassword); + final isCached = await isIconPresent(tester, Icons.check_box); + if (!isCached) await goKey(tester, keyCachePassword); await enterText(tester, keyPinForm, 'AAAAA'); await waitFor(tester, 'Accéder à mon coffre'); await goKey(tester, keyGoWalletsHome); @@ -53,3 +58,21 @@ Future restoreChest(WidgetTester tester) async { await goBack(tester); await waitFor(tester, "y'a pas de lézard"); } + +Future payChrist(WidgetTester tester) async { + await waitFor(tester, 'Rechercher'); + await goKey(tester, keyOpenSearch); + await enterText(tester, keySearchField, 'ChristCosmic'); + await goKey(tester, keyConfirmSearch); + await waitFor(tester, 'XuiQeB'); + await goKey(tester, + keyIndexerResult('5CJKhFCpdSpumgWjSZ3TQmejJuHV6iELJrtdrfs38SXuiQeB')); + await waitFor(tester, 'XuiQeB'); + await waitFor(tester, 'ĞD'); + await goKey(tester, keyPay); + await enterText(tester, keyAmountField, '2.14'); + await goKey(tester, keyConfirmPayment); + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 12)); + await goKey(tester, keyCloseTransactionScreen); + await waitFor(tester, 'XuiQeB'); +} diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 30bd14d..cc5c582 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -46,6 +46,26 @@ Future waitFor( } while (finder.evaluate().isEmpty); } +// Test if text is visible on screen, return a boolean +Future isPresent(WidgetTester tester, String text, + {Duration timeout = const Duration(seconds: 1)}) async { + try { + await waitFor(tester, text, timeout: timeout); + return true; + } catch (exception) { + return false; + } +} + +// Test if widget exist on screen, return a boolean +Future isIconPresent(WidgetTester tester, IconData icon, + {Duration timeout = const Duration(seconds: 1)}) async { + await tester.pumpAndSettle(); + final finder = find.byIcon(icon); + log.d('tatatatatatata: ${finder.evaluate()}'); + return finder.evaluate().isEmpty ? false : true; +} + extension Truncate on String { String truncate({required int max, String suffix = ''}) { return length < max diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index e83e29d..31a0db1 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -10,7 +10,8 @@ const keyConfirm = Key('keyConfirm'); const keyParameters = Key('keyParameters'); const keyContacts = Key('keyContacts'); const keyDrawerMenu = Key('keyDrawerMenu'); -const keyManageWallets = Key('keyManageWallets'); +const keyOpenWalletsHomme = Key('keyOpenWalletsHomme'); +const keyOpenSearch = Key('keyOpenSearch'); const keyRestoreChest = Key('keyRestoreChest'); // Wallets home @@ -46,6 +47,9 @@ const keyImportChest = Key('keyImportChest'); const keyViewActivity = Key('keyViewActivity'); const keyCertify = Key('keyCertify'); const keyPay = Key('keyPay'); +const keyAmountField = Key('keyAmountField'); +const keyConfirmPayment = Key('keyConfirmPayment'); +const keyCloseTransactionScreen = Key('keyCloseTransactionScreen'); // Activity view const keyListTransactions = Key('keyListTransactions'); @@ -67,8 +71,12 @@ const keyInputWord = Key('keyInputWord'); const keyGeneratedPin = Key('keyGeneratedPin'); const keyGoWalletsHome = Key('keyGoWalletsHome'); +// Search +const keySearchField = Key('keySearchField'); +const keyConfirmSearch = Key('keyConfirmSearch'); + // Unit keys Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); -Key keyIndexerResult(int keyId) => Key('keyIndexerResult$keyId'); +Key keyIndexerResult(String keyId) => Key('keyIndexerResult$keyId'); Key keyTransaction(int keyId) => Key('keyTransaction$keyId'); -Key keySearchResult(int keyId) => Key('keySearchResult$keyId'); +Key keySearchResult(String keyId) => Key('keySearchResult$keyId'); diff --git a/lib/providers/duniter_indexer.dart b/lib/providers/duniter_indexer.dart index a4570fb..e0417b7 100644 --- a/lib/providers/duniter_indexer.dart +++ b/lib/providers/duniter_indexer.dart @@ -294,7 +294,6 @@ class DuniterIndexer with ChangeNotifier { return Text('noResult'.tr()); } - int keyID = 0; double avatarSize = 55; return Expanded( child: ListView(children: [ @@ -302,7 +301,7 @@ class DuniterIndexer with ChangeNotifier { Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: keyIndexerResult(keyID++), + key: keyIndexerResult(profile['id']), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider.defaultAvatar(avatarSize), diff --git a/lib/screens/home.dart b/lib/screens/home.dart index ddff84c..071289a 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -282,6 +282,7 @@ Widget geckHome(context) { child: Material( color: orangeC, // button color child: InkWell( + key: keyOpenSearch, child: Padding( padding: const EdgeInsets.all(18), child: Image( @@ -324,7 +325,7 @@ Widget geckHome(context) { ], ), child: ClipOval( - key: keyManageWallets, + key: keyOpenWalletsHomme, child: Material( color: orangeC, // button color child: InkWell( diff --git a/lib/screens/my_contacts.dart b/lib/screens/my_contacts.dart index abe9fc0..3307e35 100644 --- a/lib/screens/my_contacts.dart +++ b/lib/screens/my_contacts.dart @@ -29,7 +29,6 @@ class ContactsScreen extends StatelessWidget { DuniterIndexer duniterIndexer = Provider.of(context, listen: false); - int keyID = 0; double avatarSize = 55; final myContacts = contactsBox.toMap().values.toList(); @@ -72,7 +71,7 @@ class ContactsScreen extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: keySearchResult(keyID++), + key: keySearchResult('keyID++'), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider diff --git a/lib/screens/search.dart b/lib/screens/search.dart index 5ab523e..ff3c6d7 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/widgets_keys.dart'; // import 'package:gecko/providers/home.dart'; import 'package:gecko/providers/search.dart'; import 'package:gecko/screens/common_elements.dart'; @@ -51,6 +52,7 @@ class SearchScreen extends StatelessWidget { Padding( padding: const EdgeInsets.symmetric(horizontal: 17), child: TextField( + key: keySearchField, controller: searchProvider.searchController, autofocus: true, maxLines: 1, @@ -91,6 +93,7 @@ class SearchScreen extends StatelessWidget { width: 410, height: 70, child: ElevatedButton( + key: keyConfirmSearch, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/search_result.dart b/lib/screens/search_result.dart index 89ccc05..c1ca7f0 100644 --- a/lib/screens/search_result.dart +++ b/lib/screens/search_result.dart @@ -32,7 +32,6 @@ class SearchResultScreen extends StatelessWidget { DuniterIndexer duniterIndexer = Provider.of(context, listen: false); - int keyID = 0; double avatarSize = 55; return Scaffold( @@ -95,7 +94,7 @@ class SearchResultScreen extends StatelessWidget { padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: keySearchResult(keyID++), + key: keySearchResult(g1Wallet.pubkey!), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index dafd381..b00c805 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -2,6 +2,7 @@ import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/providers/wallets_profiles.dart'; @@ -263,6 +264,7 @@ class TransactionInProgress extends StatelessWidget { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( + key: keyCloseTransactionScreen, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index c606cc9..45db562 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -573,6 +573,7 @@ class WalletViewScreen extends StatelessWidget { ), const SizedBox(height: 10), TextField( + key: keyAmountField, controller: walletViewProvider.payAmount, autofocus: true, maxLines: 1, @@ -618,6 +619,7 @@ class WalletViewScreen extends StatelessWidget { width: double.infinity, height: 60, child: ElevatedButton( + key: keyConfirmPayment, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background From afae4130a63edbcd597144991e0fb26998e0aca5 Mon Sep 17 00:00:00 2001 From: poka Date: Tue, 23 Aug 2022 23:46:01 +0200 Subject: [PATCH 04/28] add script to launch duniter local node before integration tests --- .gitignore | 4 +- integration_test/app_test.dart | 5 + .../duniter/data/gecko_tests.json | 74 +++ integration_test/duniter/docker-compose.yml | 18 + integration_test/launch_test.sh | 26 + integration_test/tests_utility.dart | 1 + lib/main.dart | 5 + pubspec.lock | 7 + pubspec.yaml | 2 + test/widget_test.dart | 30 -- test_driver/app.dart | 11 - test_driver/app_test.dart | 455 ------------------ 12 files changed, 141 insertions(+), 497 deletions(-) create mode 100644 integration_test/duniter/data/gecko_tests.json create mode 100644 integration_test/duniter/docker-compose.yml create mode 100755 integration_test/launch_test.sh delete mode 100644 test/widget_test.dart delete mode 100644 test_driver/app.dart delete mode 100644 test_driver/app_test.dart diff --git a/.gitignore b/.gitignore index e5924f5..b021e4e 100644 --- a/.gitignore +++ b/.gitignore @@ -55,4 +55,6 @@ scripts/private/ AppDir/ appimage-builder-cache/ AppImageBuilder.yml -android/app/build.gradle \ No newline at end of file +android/app/build.gradle +.env +integration_test/duniter/data/chains/ \ No newline at end of file diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index a30b1e0..a3f1193 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; import 'package:gecko/main.dart' as app; @@ -13,6 +15,9 @@ void main() { testWidgets('Import chests', (tester) async { app.main(); await tester.pumpAndSettle(const Duration(seconds: 1)); + final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; + + log.d('ip address: $ipAddress'); // Delete all existing chests await deleteAllWallets(tester); diff --git a/integration_test/duniter/data/gecko_tests.json b/integration_test/duniter/data/gecko_tests.json new file mode 100644 index 0000000..f874b5a --- /dev/null +++ b/integration_test/duniter/data/gecko_tests.json @@ -0,0 +1,74 @@ +{ + "first_ud": 1000, + "first_ud_reeval": 100, + "genesis_parameters": { + "genesis_certs_expire_on": 10, + "genesis_certs_min_received": 3, + "genesis_memberships_expire_on": 1051200, + "genesis_smith_certs_expire_on": 2102400, + "genesis_smith_certs_min_received": 3, + "genesis_smith_memberships_expire_on": 1051200 + }, + "identities": { + "test1": { + "balance": 1000, + "certs": ["test2", "test3", "test4"], + "pubkey": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa" + }, + "test2": { + "balance": 1000, + "certs": ["test1", "test3", "test4"], + "pubkey": "5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb" + }, + "test3": { + "balance": 1000, + "certs": ["test1", "test2", "test4"], + "pubkey": "5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p" + }, + "test4": { + "balance": 1000, + "certs": ["test1", "test2", "test3"], + "pubkey": "5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5" + } + }, + "parameters": { + "babe_epoch_duration": 30, + "cert_period": 15, + "cert_max_by_issuer": 10, + "cert_min_received_cert_to_issue_cert": 2, + "cert_validity_period": 1000, + "idty_confirm_period": 40, + "idty_creation_period": 50, + "membership_period": 1000, + "pending_membership_period": 500, + "ud_creation_period": 10, + "ud_reeval_period": 50, + "smith_cert_period": 15, + "smith_cert_max_by_issuer": 8, + "smith_cert_min_received_cert_to_issue_cert": 2, + "smith_cert_validity_period": 1000, + "smith_membership_period": 1000, + "smith_pending_membership_period": 500, + "smiths_wot_first_cert_issuable_on": 20, + "smiths_wot_min_cert_for_membership": 2, + "wot_first_cert_issuable_on": 20, + "wot_min_cert_for_create_idty_right": 2, + "wot_min_cert_for_membership": 2 + }, + "smiths": { + "test1": { + "certs": ["test2", "test3", "test4"] + }, + "test2": { + "certs": ["test1", "test3", "test4"] + }, + "test3": { + "certs": ["test1", "test2", "test4"] + }, + "test4": { + "certs": ["test1", "test2", "test3"] + } + }, + "sudo_key": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa", + "technical_committee": ["test1", "test2", "test3"] +} diff --git a/integration_test/duniter/docker-compose.yml b/integration_test/duniter/docker-compose.yml new file mode 100644 index 0000000..5180193 --- /dev/null +++ b/integration_test/duniter/docker-compose.yml @@ -0,0 +1,18 @@ +version: "3.5" + +services: + duniter-v2s-gecko-tests: + container_name: duniter-v2s-gecko-tests + image: duniter/duniter-v2s:debug-latest + command: --sealing=manual + ports: + - "127.0.0.1:9615:9615" + - "127.0.0.1:9933:9933" + - "0.0.0.0:9944:9944" + - "30333:30333" + environment: + DUNITER_INSTANCE_NAME: "gecko_tests" + DUNITER_CHAIN_NAME: "dev" + DUNITER_GENESIS_CONFIG: "/var/lib/duniter/gecko_tests.json" + volumes: + - ./data:/var/lib/duniter diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh new file mode 100755 index 0000000..b2f2a51 --- /dev/null +++ b/integration_test/launch_test.sh @@ -0,0 +1,26 @@ +#!/bin/bash + +# MP="`dirname \"$0\"`" +# MP="`( cd \"$MP\" && pwd )`" +# cd $MP + +args="$@" + +# Get local IP and set .env +ip_address=$(hostname -I | awk '{print $1}') +echo "ip_address=$ip_address" > .env + +## Start local Duniter node +cd integration_test/duniter +rm -rf data/chains +docker-compose up -d +cd ../.. + +# Start integration test +flutter test integration_test/app_test.dart + +# Stop Duniter +cd integration_test/duniter +docker-compose down + + diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index cc5c582..c6fb221 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -38,6 +38,7 @@ Future waitFor( do { if (DateTime.now().isAfter(end)) { + throw Exception('Timed out waiting for text $text'); } diff --git a/lib/main.dart b/lib/main.dart index c0fd1f1..a6d3cd6 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -16,6 +16,7 @@ import 'dart:async'; import 'dart:io'; import 'package:flutter/services.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/providers/cesium_plus.dart'; import 'package:gecko/models/chest_data.dart'; @@ -51,6 +52,10 @@ Future main() async { WidgetsFlutterBinding.ensureInitialized(); await EasyLocalization.ensureInitialized(); + if (kDebugMode) { + await dotenv.load(); + } + HomeProvider homeProvider = HomeProvider(); // DuniterIndexer _duniterIndexer = DuniterIndexer(); await initHiveForFlutter(); diff --git a/pubspec.lock b/pubspec.lock index d404e72..6fc8368 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -384,6 +384,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + flutter_dotenv: + dependency: "direct main" + description: + name: flutter_dotenv + url: "https://pub.dartlang.org" + source: hosted + version: "5.0.2" flutter_driver: dependency: "direct main" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 225f635..bdd79c1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -76,6 +76,7 @@ dependencies: dropdown_button2: ^1.6.3 pointycastle: ^3.6.1 hex: ^0.2.0 + flutter_dotenv: ^5.0.2 dev_dependencies: # flutter_launcher_icons: ^0.9.2 @@ -112,3 +113,4 @@ flutter: - assets/onBoarding/progress_bar/ - assets/walletOptions/ - sounds/ + - .env diff --git a/test/widget_test.dart b/test/widget_test.dart deleted file mode 100644 index 96c517f..0000000 --- a/test/widget_test.dart +++ /dev/null @@ -1,30 +0,0 @@ -// // This is a basic Flutter widget test. -// // -// // To perform an interaction with a widget in your test, use the WidgetTester -// // utility that Flutter provides. For example, you can send tap and scroll -// // gestures. You can also use WidgetTester to find child widgets in the widget -// // tree, read text, and verify that the values of widget properties are correct. - -// import 'package:flutter/material.dart'; -// import 'package:flutter_test/flutter_test.dart'; - -// import 'package:gecko/main.dart'; - -// void main() { -// testWidgets('Counter increments smoke test', (WidgetTester tester) async { -// // Build our app and trigger a frame. -// await tester.pumpWidget(Gecko()); - -// // Verify that our counter starts at 0. -// expect(find.text('0'), findsOneWidget); -// expect(find.text('1'), findsNothing); - -// // Tap the '+' icon and trigger a frame. -// await tester.tap(find.byIcon(Icons.add)); -// await tester.pump(); - -// // Verify that our counter has incremented. -// expect(find.text('0'), findsNothing); -// expect(find.text('1'), findsOneWidget); -// }); -// } diff --git a/test_driver/app.dart b/test_driver/app.dart deleted file mode 100644 index ec9a318..0000000 --- a/test_driver/app.dart +++ /dev/null @@ -1,11 +0,0 @@ -import 'package:flutter_driver/driver_extension.dart'; -import 'package:gecko/main.dart' as app; - -void main() { - // This line enables the extension. - enableFlutterDriverExtension(); - - // Call the `main()` function of the app, or call `runApp` with - // any widget you are interested in testing. - app.main(); -} diff --git a/test_driver/app_test.dart b/test_driver/app_test.dart deleted file mode 100644 index fa44048..0000000 --- a/test_driver/app_test.dart +++ /dev/null @@ -1,455 +0,0 @@ -import 'dart:async'; -import 'dart:io'; -import 'package:easy_localization/easy_localization.dart'; -import 'package:flutter_driver/flutter_driver.dart'; -import 'package:gecko/globals.dart'; -import 'package:test/test.dart'; -// import 'package:flutter/services.dart'; - -void main() { - int globalTimeout = 2; - group('Gecko App', () { - // First, define the Finders and use them to locate widgets from the - // test suite. Note: the Strings provided to the `byValueKey` method must - // be the same as the Strings we used for the Keys in step 1. - final manageWalletsFinder = find.byValueKey('manageWallets'); - // final buttonFinder = find.byValueKey('increment'); - - FlutterDriver? driver; - String? pinCode; - - // Connect to the Flutter driver before running any tests. - setUpAll(() async { - driver = await FlutterDriver.connect(); - await driver!.waitUntilFirstFrameRasterized(); - }); - - // Close the connection to the driver after the tests have completed. - tearDownAll(() async { - if (driver != null) { - driver!.close(); - } - }); - - // *** Global functions *** // - - // Function to tap the widget by key - Future tapOn(String key) async { - await driver!.tap(find.byValueKey(key)); - } - - // Easy get text - Future getText(String text) async { - return await driver!.getText(find.byValueKey( - text, - )); - } - - // Function to go back to previous screen - Future goBack() async { - await Process.run( - 'adb', - ['shell', 'input', 'keyevent', 'KEYCODE_BACK'], - runInShell: true, - ); - } - - // Easy sleep - Future sleep(int time) async { - await Future.delayed(Duration(milliseconds: time)); - } - - // Test if widget exist on screen, return a boolean - Future isPresent(SerializableFinder byValueKey, - {Duration timeout = const Duration(seconds: 1)}) async { - try { - await driver!.waitFor(byValueKey, timeout: timeout); - return true; - } catch (exception) { - return false; - } - } - - // Create a derivation - Future createDerivation() async { - await tapOn('addDerivation'); - await sleep(300); - } - - // Delete a derivation - Future deleteWallet(bool confirm) async { - await tapOn('deleteWallet'); - await sleep(100); - confirm ? await tapOn('confirmDeleting') : await tapOn('cancelDeleting'); - await sleep(300); - } - - // Delete all wallets - Future deleteAllWallets() async { - await tapOn('drawerMenu'); - await sleep(300); - await tapOn('parameters'); - await sleep(300); - await tapOn('deleteAllWallets'); - await sleep(300); - await tapOn('confirmDeletingAllWallets'); - await sleep(300); - } - - // Fast creation of new Keychain - Future createNewKeychain(String name) async { - await tapOn('drawerMenu'); - await sleep(300); - await tapOn('parameters'); - await sleep(300); - await tapOn('generateKeychain'); - while (await getText('generatedPin') == '') { - log.d('Waiting for pin code generation...'); - await sleep(100); - } - pinCode = await getText('generatedPin'); - await tapOn('storeKeychain'); - await sleep(100); - await driver!.enterText('triche'); - await tapOn('walletName'); - await driver!.enterText(name); - await sleep(50); - await tapOn('confirmStorage'); - await sleep(300); - return pinCode; - } - - // *** Begin of tests *** // - - test('OnBoarding - Open wallets management', ( - {timeout = Timeout.none}) async { - // await driver.runUnsynchronized(() async { // Needed if we want to manage async drivers - await driver!.tap(manageWalletsFinder); - - // If a wallet exist, go to delete theme all - if (!await isPresent(find.byValueKey('goStep1'))) { - await goBack(); - - await deleteAllWallets(); - - await driver!.tap(manageWalletsFinder); - } - - // Get the SerializableFinder for text widget with key 'textOnboarding' - SerializableFinder textOnboarding = find.byValueKey( - 'textOnboarding', - ); - - await sleep(100); - - // Verify onboarding is starting, with text - expect(await driver!.getText(textOnboarding), - "Je ne connais pour l’instant aucun de vos portefeuilles.\n\nVous pouvez en créer un nouveau, ou bien importer un portefeuille Cesium existant."); - }); - - test('OnBoarding - Go to create restore sentance', ( - {timeout = Timeout.none}) async { - await tapOn('goStep1'); - await tapOn('goStep2'); - await tapOn('goStep3'); - await tapOn('goStep4'); - await tapOn('goStep5'); - await tapOn('goStep6'); - - expect( - await driver!.getText(find.byValueKey( - 'step6', - )), - "iGeneratedYourMnemonicKeepItSecret".tr()); - }); - - test('OnBoarding - Generate sentance and confirme it', ( - {timeout = Timeout.none}) async { - await tapOn('goStep7'); - - while (await getText('word1') == '...') { - log.d('Waiting for Mnemonic generation...'); - await sleep(100); - } - - Future selectWord() async { - List words = [for (var i = 1; i <= 13; i += 1) i]; - - for (var j = 1; j < 13; j++) { - words[j] = await getText('word$j'); - } - expect( - await getText('step7'), "C'est le moment de noter votre phrase !"); - - await tapOn('goStep8'); - await sleep(200); - - String goodWord = words[int.parse( - await getText('askedWord'), - )]; - - // Enter the expected word - await driver!.enterText(goodWord); - - // Check if word is valid - await driver!.waitFor(find.text("C'est le bon mot !")); - - // Continue onboarding workflow - await tapOn('goStep9'); - } - - await selectWord(); - - //Go back 2 times to mnemonic generation screen - await goBack(); - await goBack(); - await sleep(100); - - // Generate 3 times mnemonic - await tapOn('generateMnemonic'); - await tapOn('generateMnemonic'); - await tapOn('generateMnemonic'); - await sleep(500); - - await selectWord(); - }); - test('OnBoarding - Generate secret code and confirm it', ( - {timeout = Timeout.none}) async { - expect(await getText('step9'), - "Super !\n\nJe vais maintenant créer votre code secret. \n\nVotre code secret chiffre votre coffre de clefs, ce qui le rend inutilisable par d’autres, par exemple si vous perdez votre téléphone ou si on vous le vole."); - await sleep(800); - await tapOn('goStep10'); - await sleep(50); - await tapOn('goStep11'); - - while (await getText('generatedPin') == '') { - log.d('Waiting for pin code generation...'); - await sleep(100); - } - - // Change secret code 4 times - for (int i = 0; i < 4; i++) { - await tapOn('changeSecretCode'); - } - - await sleep(500); - pinCode = await getText('generatedPin'); - - await tapOn('goStep12'); - await sleep(300); - - // //Enter bad secret code - // await driver.enterText('abcde'); - // await tapOn('formKey'); - // await sleep(1500); - // await tapOn('formKey2'); - - //Enter good secret code - await driver!.enterText(pinCode!); - - expect(await getText('step13'), - "Top !\n\nVotre coffre et votre portefeuille ont été créés avec un immense succès.\n\nFélicitations !"); - }); - - test('My wallets - Rename first derivation', ( - {timeout = const Duration(seconds: 2)}) async { - await tapOn('goWalletHome'); - - expect(await getText('myWallets'), "geckoChest".tr()); - await sleep(300); - - // Go to first derivation and rename it - await driver!.tap(find.text('Mon portefeuille courant')); - await sleep(300); - await tapOn('renameWallet'); - await sleep(100); - await tapOn('walletName'); - await sleep(100); - await driver!.enterText('Renommage wallet 1'); - await sleep(300); - await tapOn('renameWallet'); - await sleep(400); - await driver!.waitFor(find.text('Renommage wallet 1'), timeout: timeout); - // expect(await getText('walletName'), "Renommage wallet 1"); - await goBack(); - }); - - test('My wallets - Create a derivations, open thems, tap all buttons', ( - {timeout = const Duration(seconds: 2)}) async { - await driver!.waitFor(find.text('Renommage wallet 1'), timeout: timeout); - // Add a second derivation - await createDerivation(); - - // Go to second derivation options - await driver!.tap(find.text('Portefeuille 2')); - await sleep(100); - - // Test options - await tapOn('displayBalance'); - await tapOn('displayHistory'); - await sleep(300); - await goBack(); - await tapOn('displayBalance'); - await sleep(100); - await tapOn('displayBalance'); - await sleep(100); - await tapOn('displayBalance'); - await tapOn('setDefaultWallet'); - await sleep(50); - await tapOn('copyPubkey'); - await driver!.waitFor(find - .text('Cette clé publique a été copié dans votre presse-papier.')); - await goBack(); - - // Add a third derivation - await createDerivation(); - - // Add a fourth derivation - await createDerivation(); - await sleep(50); - - // Go to third derivation options - await driver!.tap(find.text('Portefeuille 3')); - await sleep(100); - await tapOn('displayBalance'); - - // Delete third derivation - await deleteWallet(true); - }); - - test('My wallets - Extra tests', ( - {timeout = const Duration(seconds: 2)}) async { - // Add derivation 5,6 and 7 - await driver!.waitFor(find.text('Portefeuille 4'), timeout: timeout); - await createDerivation(); - await createDerivation(); - await createDerivation(); - - // Go home and come back to my wallets view - await goBack(); - await sleep(100); - await tapOn('manageWallets'); - await sleep(200); - //Enter secret code - await driver!.enterText(pinCode!); - await sleep(200); - - // Go to derivation 6 and delete it - await driver!.tap(find.text('Portefeuille 6')); - await sleep(100); - await deleteWallet(true); - - // Go to 2nd derivation and check if it's de default - await driver!.tap(find.text('Portefeuille 2')); - await driver!.waitFor(find.text('Ce portefeuille est celui par defaut')); - await tapOn('setDefaultWallet'); - await sleep(100); - await driver!.waitFor(find.text('Ce portefeuille est celui par defaut')); - await sleep(300); - - // Display history, copy pubkey, go back and rename wallet name - await tapOn('displayHistory'); - await sleep(400); - await tapOn('copyPubkey'); - await driver!.waitFor(find - .text('Cette clé publique a été copié dans votre presse-papier.')); - await sleep(800); - await goBack(); - await sleep(300); - await tapOn('renameWallet'); - await sleep(100); - await tapOn('walletName'); - await sleep(100); - await driver!.enterText('Renommage wallet 2'); - await sleep(300); - await tapOn('renameWallet'); - await sleep(400); - await goBack(); - await driver!.waitFor(find.text('Renommage wallet 2')); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await createDerivation(); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await createDerivation(); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await createDerivation(); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await createDerivation(); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await createDerivation(); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await createDerivation(); - await driver!.scrollIntoView(find.text('+')); - await createDerivation(); - await sleep(400); - - // Scroll the wallet screen until Derivation 20 and open it - await driver!.scrollUntilVisible( - find.byValueKey('listWallets'), - find.text('Portefeuille 20'), - dyScroll: -300.0, - ); - - await driver!.waitFor(find.text('Portefeuille 20')); - await sleep(400); - await driver!.tap(find.text('Portefeuille 20')); - await tapOn('copyPubkey'); - }); - - test('Search - Search Pi profile, navigate in history transactions', ( - {timeout = const Duration(seconds: 2)}) async { - await driver!.waitFor(find.text('Portefeuille 20'), timeout: timeout); - await goBack(); - await goBack(); - await sleep(200); - await tapOn('searchIcon'); - await sleep(400); - await driver!.enterText('D2meevcAHFTS2gQMvmRW5Hzi25jDdikk4nC4u1FkwRaU'); - await sleep(100); - await tapOn('copyPubkey'); - await sleep(500); - await tapOn('switchPayHistory'); - await sleep(1200); - // await driver.scrollIntoView(find.byValueKey('listTransactions')); - await driver!.scrollUntilVisible( - find.byValueKey('listTransactions'), - find.byValueKey('transaction35'), - dyScroll: -600.0, - ); - await sleep(100); - await tapOn('transaction33'); - await driver!.waitFor(find.text('Commentaire:')); - - // Want to paste pubkey copied, but doesn't work actualy with flutter driver: https://github.com/flutter/flutter/issues/47448 - // final ClipboardData pubkeyCopied = - // await Clipboard.getData(Clipboard.kTextPlain); - // await driver.enterText(pubkeyCopied.text); - - await sleep(300); - }, timeout: Timeout(Duration(minutes: globalTimeout))); - - test('Wallet generation - Fast wallets generations', ( - {timeout = const Duration(seconds: 2)}) async { - await driver!.waitFor(find.text('Commentaire:'), timeout: timeout); - await goBack(); - await goBack(); - await deleteAllWallets(); - await sleep(100); - final String? pincode = await (createNewKeychain('Fast wallet')); - await sleep(200); - await driver!.enterText(pincode!); - await sleep(100); - await createDerivation(); - await sleep(100); - await driver!.tap(find.text('Fast wallet')); - await driver!.waitFor(find.text('Fast wallet')); - // Wait 3 seconds at the end - await sleep(3000); - }); - }, timeout: Timeout(Duration(minutes: globalTimeout))); -} From 5744155400daf546d17bbe1dd82023d87b02e8ed Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 24 Aug 2022 06:36:26 +0200 Subject: [PATCH 05/28] can spawn new block just after transactions --- integration_test/app_test.dart | 54 ++++++++++++++----- .../duniter/data/gecko_tests.json | 20 +++---- integration_test/launch_test.sh | 1 + integration_test/tests_utility.dart | 9 ++-- lib/models/widgets_keys.dart | 5 +- lib/providers/duniter_indexer.dart | 2 +- lib/providers/substrate_sdk.dart | 8 ++- lib/screens/home.dart | 22 ++++---- lib/screens/settings.dart | 6 +++ 9 files changed, 90 insertions(+), 37 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index a3f1193..47b178f 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -4,8 +4,10 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; +import 'package:gecko/providers/substrate_sdk.dart'; import 'package:integration_test/integration_test.dart'; import 'package:gecko/main.dart' as app; +import 'package:provider/provider.dart'; import 'tests_utility.dart'; void main() { @@ -15,9 +17,9 @@ void main() { testWidgets('Import chests', (tester) async { app.main(); await tester.pumpAndSettle(const Duration(seconds: 1)); - final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; - log.d('ip address: $ipAddress'); + // Change Duniter endpoint to local + await changeNode(tester); // Delete all existing chests await deleteAllWallets(tester); @@ -25,12 +27,33 @@ void main() { // Restore a chest await restoreChest(tester); - // Execute a transaction to ChristCosmic - await payChrist(tester); + // Execute a transaction to test2 + await payTest2(tester); }); }); } +Future changeNode(WidgetTester tester) async { + final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; + log.d('ip address: $ipAddress'); + + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); + await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); + await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); + // await sleep(tester, 10000); + await goKey(tester, keyConnectToEndpoint); + await isIconPresent(tester, Icons.add_card_sharp, + timeout: const Duration(seconds: 8)); + await goBack(tester); + // final BuildContext context = tester.element(find.byKey(keyDrawerMenu)); + // SubstrateSdk sub = Provider.of(context, listen: false); + // await sub.spawnBlock(3); + + // await waitFor(tester, 'Vous êtes bien connecté'); +} + // Customs actions Future deleteAllWallets(WidgetTester tester) async { if (await isPresent(tester, 'Rechercher')) { @@ -46,7 +69,7 @@ Future restoreChest(WidgetTester tester) async { await goKey(tester, keyRestoreChest); Clipboard.setData(const ClipboardData( text: - 'smart joy blossom stomach champion fun diary relief gossip hospital logic bike')); + 'pipe paddle ketchup filter life ice feel embody glide quantum ride usage')); await tester.pumpAndSettle(); await goKey(tester, keyPastMnemonic); await tester.pumpAndSettle(); @@ -64,20 +87,27 @@ Future restoreChest(WidgetTester tester) async { await waitFor(tester, "y'a pas de lézard"); } -Future payChrist(WidgetTester tester) async { +Future payTest2(WidgetTester tester) async { await waitFor(tester, 'Rechercher'); await goKey(tester, keyOpenSearch); - await enterText(tester, keySearchField, 'ChristCosmic'); + await enterText(tester, keySearchField, + '5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb'); await goKey(tester, keyConfirmSearch); - await waitFor(tester, 'XuiQeB'); + await waitFor(tester, 'Hd8Whb'); await goKey(tester, - keyIndexerResult('5CJKhFCpdSpumgWjSZ3TQmejJuHV6iELJrtdrfs38SXuiQeB')); - await waitFor(tester, 'XuiQeB'); + keySearchResult('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb')); + await waitFor(tester, 'Hd8Whb'); await waitFor(tester, 'ĞD'); await goKey(tester, keyPay); await enterText(tester, keyAmountField, '2.14'); await goKey(tester, keyConfirmPayment); - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 12)); + await sleep(tester); + final BuildContext context = + tester.element(find.byKey(keyCloseTransactionScreen)); + SubstrateSdk sub = Provider.of(context, listen: false); + await sub.spawnBlock(); + + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); - await waitFor(tester, 'XuiQeB'); + await waitFor(tester, 'Hd8Whb'); } diff --git a/integration_test/duniter/data/gecko_tests.json b/integration_test/duniter/data/gecko_tests.json index f874b5a..6e18849 100644 --- a/integration_test/duniter/data/gecko_tests.json +++ b/integration_test/duniter/data/gecko_tests.json @@ -1,8 +1,8 @@ { - "first_ud": 1000, + "first_ud": 10000, "first_ud_reeval": 100, "genesis_parameters": { - "genesis_certs_expire_on": 10, + "genesis_certs_expire_on": 2102400, "genesis_certs_min_received": 3, "genesis_memberships_expire_on": 1051200, "genesis_smith_certs_expire_on": 2102400, @@ -11,22 +11,22 @@ }, "identities": { "test1": { - "balance": 1000, + "balance": 10000, "certs": ["test2", "test3", "test4"], "pubkey": "5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa" }, "test2": { - "balance": 1000, + "balance": 10000, "certs": ["test1", "test3", "test4"], "pubkey": "5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb" }, "test3": { - "balance": 1000, + "balance": 10000, "certs": ["test1", "test2", "test4"], "pubkey": "5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p" }, "test4": { - "balance": 1000, + "balance": 10000, "certs": ["test1", "test2", "test3"], "pubkey": "5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5" } @@ -50,10 +50,10 @@ "smith_membership_period": 1000, "smith_pending_membership_period": 500, "smiths_wot_first_cert_issuable_on": 20, - "smiths_wot_min_cert_for_membership": 2, - "wot_first_cert_issuable_on": 20, - "wot_min_cert_for_create_idty_right": 2, - "wot_min_cert_for_membership": 2 + "smiths_wot_min_cert_for_membership": 3, + "wot_first_cert_issuable_on": 0, + "wot_min_cert_for_create_idty_right": 3, + "wot_min_cert_for_membership": 3 }, "smiths": { "test1": { diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh index b2f2a51..482dccd 100755 --- a/integration_test/launch_test.sh +++ b/integration_test/launch_test.sh @@ -12,6 +12,7 @@ echo "ip_address=$ip_address" > .env ## Start local Duniter node cd integration_test/duniter +docker-compose down rm -rf data/chains docker-compose up -d cd ../.. diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index c6fb221..760801e 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -3,12 +3,16 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; +Future sleep(WidgetTester tester, [int time = 1000]) async { + await Future.delayed(Duration(milliseconds: time)); +} + Future goKey(WidgetTester tester, Key buttonKey, - {Finder? customFinder, int duration = 100}) async { + {Finder? customFinder, int duration = 100, bool selectLast = false}) async { await tester.pumpAndSettle(Duration(milliseconds: duration)); final Finder finder = customFinder ?? find.byKey(buttonKey); log.d('INTEGRATION TEST: Tap on ${finder.description}}'); - await tester.tap(finder); + await tester.tap(selectLast ? finder.last : finder); // await tester.pumpAndSettle(Duration(milliseconds: duration)); } @@ -38,7 +42,6 @@ Future waitFor( do { if (DateTime.now().isAfter(end)) { - throw Exception('Timed out waiting for text $text'); } diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index 31a0db1..d5ca4c3 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -61,6 +61,9 @@ const keyCachePassword = Key('keyCachePassword'); // Settings const keyDeleteAllWallets = Key('keyDeleteAllWallets'); +const keySelectDuniterNodeDropDown = Key('keySelectDuniterNodeDropDown'); +const keyCustomDuniterEndpoint = Key('keyCustomDuniterEndpoint'); +const keyConnectToEndpoint = Key('keyConnectToEndpoint'); // Onboarding const keyPastMnemonic = Key('keyPastMnemonic'); @@ -77,6 +80,6 @@ const keyConfirmSearch = Key('keyConfirmSearch'); // Unit keys Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); -Key keyIndexerResult(String keyId) => Key('keyIndexerResult$keyId'); Key keyTransaction(int keyId) => Key('keyTransaction$keyId'); Key keySearchResult(String keyId) => Key('keySearchResult$keyId'); +Key keySelectDuniterNode(String keyId) => Key('keySelectDuniterNode$keyId'); diff --git a/lib/providers/duniter_indexer.dart b/lib/providers/duniter_indexer.dart index e0417b7..8d6123b 100644 --- a/lib/providers/duniter_indexer.dart +++ b/lib/providers/duniter_indexer.dart @@ -301,7 +301,7 @@ class DuniterIndexer with ChangeNotifier { Padding( padding: const EdgeInsets.symmetric(horizontal: 5), child: ListTile( - key: keyIndexerResult(profile['id']), + key: keySearchResult(profile['id']), horizontalTitleGap: 40, contentPadding: const EdgeInsets.all(5), leading: cesiumPlusProvider.defaultAvatar(avatarSize), diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 13a85cf..6f18f69 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -873,7 +873,6 @@ newKeySig: $newKeySig"""); keyring.current.pubKey, ); - log.d(sender.address); TxInfoData txInfo; txInfo = TxInfoData( @@ -940,6 +939,13 @@ newKeySig: $newKeySig"""); await sdk.api.keyring.deleteAccount(keyring, keypair); } + Future spawnBlock([int number = 1]) async { + for (var i = 1; i <= number; i++) { + await sdk.webView! + .evalJavascript('api.rpc.engine.createBlock(true, true)'); + } + } + void reload() { notifyListeners(); } diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 071289a..9a800f3 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -40,6 +40,9 @@ class HomeScreen extends StatelessWidget { final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); + // sub.spawnBlock(); + // log.d('message'); + isTall = false; ratio = 1; if (MediaQuery.of(context).size.height >= 930) { @@ -122,17 +125,18 @@ class HomeScreen extends StatelessWidget { myWalletProvider.rebuildWidget(); } - var connectivityResult = - await (Connectivity().checkConnectivity()); + // var connectivityResult = + // await (Connectivity().checkConnectivity()); + + // if (connectivityResult != ConnectivityResult.mobile && + // connectivityResult != ConnectivityResult.wifi) { + // homeProvider.changeMessage( + // "notConnectedToInternet".tr(), 0); + // sub.nodeConnected = false; + // } + HomeProvider homeProvider = Provider.of(ctx, listen: false); - if (connectivityResult != ConnectivityResult.mobile && - connectivityResult != ConnectivityResult.wifi) { - homeProvider.changeMessage( - "notConnectedToInternet".tr(), 0); - sub.nodeConnected = false; - } - Connectivity() .onConnectivityChanged .listen((ConnectivityResult result) async { diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index f219eea..5c9e325 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -116,11 +116,14 @@ class SettingsScreen extends StatelessWidget { Icon(sub.nodeConnected && !sub.isLoadingEndpoint ? Icons.check : Icons.close), + if (sub.nodeConnected && !sub.isLoadingEndpoint) + const Icon(Icons.add_card_sharp, size: 0.01), const Spacer(), SizedBox( width: 265, child: Consumer(builder: (context, set, _) { return DropdownButtonHideUnderline( + key: keySelectDuniterNodeDropDown, child: DropdownButton( // alignment: AlignmentDirectional.topStart, value: selectedDuniterEndpoint, @@ -128,6 +131,7 @@ class SettingsScreen extends StatelessWidget { items: duniterBootstrapNodes .map((NetworkParams endpointParams) { return DropdownMenuItem( + key: keySelectDuniterNode(endpointParams.endpoint!), value: endpointParams.endpoint, child: Text(endpointParams.endpoint!), ); @@ -146,6 +150,7 @@ class SettingsScreen extends StatelessWidget { ? CircularProgressIndicator(color: orangeC) : Consumer(builder: (context, set, _) { return IconButton( + key: keyConnectToEndpoint, icon: Icon( Icons.send, color: selectedDuniterEndpoint != @@ -186,6 +191,7 @@ class SettingsScreen extends StatelessWidget { width: 200, height: 50, child: TextField( + key: keyCustomDuniterEndpoint, controller: endpointController, autocorrect: false, ), From fbc8cbd0d9c35e0cb90a5095745ce94c8975b5de Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 24 Aug 2022 06:44:40 +0200 Subject: [PATCH 06/28] improve spawnBlock in tests --- integration_test/app_test.dart | 10 +--------- integration_test/tests_utility.dart | 9 +++++++++ lib/screens/home.dart | 3 --- 3 files changed, 10 insertions(+), 12 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 47b178f..ca30a7b 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -4,10 +4,8 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; -import 'package:gecko/providers/substrate_sdk.dart'; import 'package:integration_test/integration_test.dart'; import 'package:gecko/main.dart' as app; -import 'package:provider/provider.dart'; import 'tests_utility.dart'; void main() { @@ -47,9 +45,6 @@ Future changeNode(WidgetTester tester) async { await isIconPresent(tester, Icons.add_card_sharp, timeout: const Duration(seconds: 8)); await goBack(tester); - // final BuildContext context = tester.element(find.byKey(keyDrawerMenu)); - // SubstrateSdk sub = Provider.of(context, listen: false); - // await sub.spawnBlock(3); // await waitFor(tester, 'Vous êtes bien connecté'); } @@ -102,10 +97,7 @@ Future payTest2(WidgetTester tester) async { await enterText(tester, keyAmountField, '2.14'); await goKey(tester, keyConfirmPayment); await sleep(tester); - final BuildContext context = - tester.element(find.byKey(keyCloseTransactionScreen)); - SubstrateSdk sub = Provider.of(context, listen: false); - await sub.spawnBlock(); + await spawnBlock(tester, keyCloseTransactionScreen); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 760801e..36946ba 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -2,6 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/providers/substrate_sdk.dart'; +import 'package:provider/provider.dart'; Future sleep(WidgetTester tester, [int time = 1000]) async { await Future.delayed(Duration(milliseconds: time)); @@ -70,6 +72,13 @@ Future isIconPresent(WidgetTester tester, IconData icon, return finder.evaluate().isEmpty ? false : true; } +Future spawnBlock(WidgetTester tester, Key customKey) async { + final BuildContext context = + tester.element(find.byKey(customKey)); + SubstrateSdk sub = Provider.of(context, listen: false); + await sub.spawnBlock(); +} + extension Truncate on String { String truncate({required int max, String suffix = ''}) { return length < max diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 9a800f3..22544f9 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -40,9 +40,6 @@ class HomeScreen extends StatelessWidget { final bool isWalletsExists = myWalletProvider.checkIfWalletExist(); - // sub.spawnBlock(); - // log.d('message'); - isTall = false; ratio = 1; if (MediaQuery.of(context).size.height >= 930) { From a03f71153994fe9a0ed849875e62d9d7f07b9764 Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 24 Aug 2022 21:53:16 +0200 Subject: [PATCH 07/28] add certtification workflow test --- integration_test/app_test.dart | 105 ---------- .../duniter/data/gecko_tests.json | 2 +- integration_test/gecko_complete.dart | 193 ++++++++++++++++++ integration_test/launch_test.sh | 5 +- integration_test/tests_utility.dart | 20 +- lib/main.dart | 7 +- lib/models/widgets_keys.dart | 9 +- lib/providers/home.dart | 6 +- lib/providers/substrate_sdk.dart | 3 +- lib/providers/wallet_options.dart | 4 +- lib/screens/home.dart | 34 +-- lib/screens/myWallets/choose_wallet.dart | 2 + lib/screens/myWallets/wallet_options.dart | 2 +- lib/screens/myWallets/wallets_home.dart | 1 + lib/screens/wallet_view.dart | 2 +- 15 files changed, 245 insertions(+), 150 deletions(-) delete mode 100644 integration_test/app_test.dart create mode 100644 integration_test/gecko_complete.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart deleted file mode 100644 index ca30a7b..0000000 --- a/integration_test/app_test.dart +++ /dev/null @@ -1,105 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:gecko/globals.dart'; -import 'package:gecko/models/widgets_keys.dart'; -import 'package:integration_test/integration_test.dart'; -import 'package:gecko/main.dart' as app; -import 'tests_utility.dart'; - -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - - group('Ğecko basics', () { - testWidgets('Import chests', (tester) async { - app.main(); - await tester.pumpAndSettle(const Duration(seconds: 1)); - - // Change Duniter endpoint to local - await changeNode(tester); - - // Delete all existing chests - await deleteAllWallets(tester); - - // Restore a chest - await restoreChest(tester); - - // Execute a transaction to test2 - await payTest2(tester); - }); - }); -} - -Future changeNode(WidgetTester tester) async { - final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; - log.d('ip address: $ipAddress'); - - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); - await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); - await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); - // await sleep(tester, 10000); - await goKey(tester, keyConnectToEndpoint); - await isIconPresent(tester, Icons.add_card_sharp, - timeout: const Duration(seconds: 8)); - await goBack(tester); - - // await waitFor(tester, 'Vous êtes bien connecté'); -} - -// Customs actions -Future deleteAllWallets(WidgetTester tester) async { - if (await isPresent(tester, 'Rechercher')) { - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keyDeleteAllWallets); - await goKey(tester, keyConfirm); - await tester.pumpAndSettle(); - } -} - -Future restoreChest(WidgetTester tester) async { - await goKey(tester, keyRestoreChest); - Clipboard.setData(const ClipboardData( - text: - 'pipe paddle ketchup filter life ice feel embody glide quantum ride usage')); - await tester.pumpAndSettle(); - await goKey(tester, keyPastMnemonic); - await tester.pumpAndSettle(); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - final isCached = await isIconPresent(tester, Icons.check_box); - if (!isCached) await goKey(tester, keyCachePassword); - await enterText(tester, keyPinForm, 'AAAAA'); - await waitFor(tester, 'Accéder à mon coffre'); - await goKey(tester, keyGoWalletsHome); - await waitFor(tester, 'ĞD'); - await goBack(tester); - await waitFor(tester, "y'a pas de lézard"); -} - -Future payTest2(WidgetTester tester) async { - await waitFor(tester, 'Rechercher'); - await goKey(tester, keyOpenSearch); - await enterText(tester, keySearchField, - '5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb'); - await goKey(tester, keyConfirmSearch); - await waitFor(tester, 'Hd8Whb'); - await goKey(tester, - keySearchResult('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb')); - await waitFor(tester, 'Hd8Whb'); - await waitFor(tester, 'ĞD'); - await goKey(tester, keyPay); - await enterText(tester, keyAmountField, '2.14'); - await goKey(tester, keyConfirmPayment); - await sleep(tester); - await spawnBlock(tester, keyCloseTransactionScreen); - - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen); - await waitFor(tester, 'Hd8Whb'); -} diff --git a/integration_test/duniter/data/gecko_tests.json b/integration_test/duniter/data/gecko_tests.json index 6e18849..1cbcf63 100644 --- a/integration_test/duniter/data/gecko_tests.json +++ b/integration_test/duniter/data/gecko_tests.json @@ -2,7 +2,7 @@ "first_ud": 10000, "first_ud_reeval": 100, "genesis_parameters": { - "genesis_certs_expire_on": 2102400, + "genesis_certs_expire_on": 50, "genesis_certs_min_received": 3, "genesis_memberships_expire_on": 1051200, "genesis_smith_certs_expire_on": 2102400, diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart new file mode 100644 index 0000000..1a42d4c --- /dev/null +++ b/integration_test/gecko_complete.dart @@ -0,0 +1,193 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:gecko/main.dart' as app; +import 'tests_utility.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('Gecko complete', (tester) async { + app.main(); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Change Duniter endpoint to local + await changeNode(tester); + + // Delete all existing chests + await deleteAllWallets(tester); + + // Restore a chest + await restoreChest(tester); + + // Execute a transaction to test2 + await payTest2(tester); + + // Certify test5 account with 3 account to become member + await certifyTest5(tester); + }); +} + +Future changeNode(WidgetTester tester) async { + final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; + log.d('ip address: $ipAddress'); + + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); + await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); + await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); + // await sleep(tester, 10000); + await goKey(tester, keyConnectToEndpoint); + await isIconPresent(tester, Icons.add_card_sharp, + timeout: const Duration(seconds: 8)); + await goBack(tester); + + // await waitFor(tester, 'Vous êtes bien connecté'); +} + +// Customs actions +Future deleteAllWallets(WidgetTester tester) async { + if (await isPresent(tester, 'Rechercher')) { + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keyDeleteAllWallets); + await goKey(tester, keyConfirm); + await tester.pumpAndSettle(); + } +} + +Future restoreChest(WidgetTester tester) async { + await goKey(tester, keyRestoreChest); + Clipboard.setData(const ClipboardData( + text: + 'pipe paddle ketchup filter life ice feel embody glide quantum ride usage')); + await tester.pumpAndSettle(); + await goKey(tester, keyPastMnemonic); + await tester.pumpAndSettle(); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + final isCached = await isIconPresent(tester, Icons.check_box); + if (!isCached) await goKey(tester, keyCachePassword); + await enterText(tester, keyPinForm, 'AAAAA'); + await waitFor(tester, 'Accéder à mon coffre'); + await goKey(tester, keyGoWalletsHome); + await waitFor(tester, 'ĞD'); + + // Test add a new derivation + await addDerivation(tester); + await goKey(tester, + keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); + await goKey(tester, keyCopyAddress); + await waitFor(tester, 'Cette adresse a été copié'); + await goBack(tester); + await goBack(tester); + await waitFor(tester, "y'a pas de lézard"); +} + +Future payTest2(WidgetTester tester) async { + await waitFor(tester, 'Rechercher'); + await goKey(tester, keyOpenSearch); + final addressToSearch = (await Clipboard.getData('text/plain'))!.text; + final endAddress = addressToSearch!.substring(addressToSearch.length - 6); + expect(addressToSearch, '5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R'); + await enterText(tester, keySearchField, addressToSearch); + await goKey(tester, keyConfirmSearch); + await waitFor(tester, endAddress); + await goKey(tester, keySearchResult(addressToSearch)); + await waitFor(tester, endAddress); + await waitFor(tester, '0.0 ĞD'); + await goKey(tester, keyPay); + await enterText(tester, keyAmountField, '12.14'); + await goKey(tester, keyConfirmPayment); + // await sleep(tester); + await spawnBlock(tester, keyCloseTransactionScreen); + + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); + await goKey(tester, keyCloseTransactionScreen); + await waitFor(tester, '12.14'); + await spawnBlock(tester, keyViewActivity); + await waitFor(tester, '9.14'); +} + +Future addDerivation(WidgetTester tester) async { + await goKey(tester, keyAddDerivation); + await waitFor(tester, 'Portefeuille 5'); +} + +Future certifyTest5(WidgetTester tester) async { + // Create identity with Test1 account + // await spawnBlock(tester, keyViewActivity, 5); + // await sleep(tester); + await goKey(tester, keyCertify); + await goKey(tester, keyConfirm); + await spawnBlock(tester, keyViewActivity); + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); + await goKey(tester, keyCloseTransactionScreen); + await waitFor(tester, 'Identité créée'); + + // Confirm Identity Test5 + await goKey(tester, keyAppBarChest, duration: 300); + await goKey(tester, + keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); + await goKey(tester, keyCopyAddress); + await goKey(tester, keyConfirmIdentity); + await enterText(tester, keyEnterIdentityUsername, 'test5'); + await goKey(tester, keyConfirm); + await spawnBlock(tester, keyCloseTransactionScreen); + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); + await goKey(tester, keyCloseTransactionScreen); + await waitFor(tester, 'Identité confirmée'); + await goBack(tester); + await goKey(tester, + keyOpenWallet('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb')); + await goKey(tester, keySetDefaultWallet); + await waitFor(tester, 'Ce portefeuille est celui par defaut'); + + await goKey(tester, keyAppBarSearch); + final addressToSearch = (await Clipboard.getData('text/plain'))!.text; + final endAddress = addressToSearch!.substring(addressToSearch.length - 6); + expect(addressToSearch, '5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R'); + await enterText(tester, keySearchField, addressToSearch); + await goKey(tester, keyConfirmSearch); + await waitFor(tester, endAddress); + await goKey(tester, keySearchResult(addressToSearch)); + await waitFor(tester, endAddress); + await waitFor(tester, '1'); + + // Certify with test2 account + await goKey(tester, keyCertify); + await goKey(tester, keyConfirm); + await spawnBlock(tester, keyViewActivity); + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); + await goKey(tester, keyCloseTransactionScreen); + await waitFor(tester, '2'); + + // Change default wallet to test3 + await goKey(tester, keyPay); + await goKey(tester, keyChangeChest); + await goKey(tester, + keySelectThisWallet('5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p')); + await goKey(tester, keyConfirm); + await sleep(tester); + + // Certify with test3 account + await goKey(tester, keyCertify); + await goKey(tester, keyConfirm); + await spawnBlock(tester, keyViewActivity); + await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); + await goKey(tester, keyCloseTransactionScreen); + await waitFor(tester, 'Vous devez attendre'); + + // Check if test5 is member + await goKey(tester, keyAppBarChest, duration: 300); + await goKey(tester, + keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); + await waitFor(tester, 'Membre validé !'); +} diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh index 482dccd..aa72d85 100755 --- a/integration_test/launch_test.sh +++ b/integration_test/launch_test.sh @@ -4,7 +4,8 @@ # MP="`( cd \"$MP\" && pwd )`" # cd $MP -args="$@" +testName=$1 +[[ ! $testName ]] && testName='gecko_complete' # Get local IP and set .env ip_address=$(hostname -I | awk '{print $1}') @@ -18,7 +19,7 @@ docker-compose up -d cd ../.. # Start integration test -flutter test integration_test/app_test.dart +flutter test integration_test/$testName.dart # Stop Duniter cd integration_test/duniter diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 36946ba..50130a6 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -1,10 +1,11 @@ -// CUSTOM METHODES import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; +// CUSTOM METHODS + Future sleep(WidgetTester tester, [int time = 1000]) async { await Future.delayed(Duration(milliseconds: time)); } @@ -72,17 +73,10 @@ Future isIconPresent(WidgetTester tester, IconData icon, return finder.evaluate().isEmpty ? false : true; } -Future spawnBlock(WidgetTester tester, Key customKey) async { - final BuildContext context = - tester.element(find.byKey(customKey)); +Future spawnBlock(WidgetTester tester, Key customKey, [int number = 1]) async { + await sleep(tester, 1000); + final BuildContext context = tester.element(find.byKey(customKey)); SubstrateSdk sub = Provider.of(context, listen: false); - await sub.spawnBlock(); -} - -extension Truncate on String { - String truncate({required int max, String suffix = ''}) { - return length < max - ? this - : '${substring(0, substring(0, max - suffix.length).lastIndexOf(" "))}$suffix'; - } + sub.spawnBlock(number); + await sleep(tester, 500); } diff --git a/lib/main.dart b/lib/main.dart index a6d3cd6..a7262eb 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -110,7 +110,7 @@ Future main() async { supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')], path: 'assets/translations', fallbackLocale: const Locale('en'), - child: Gecko(indexerEndpoint), + child: const Gecko(), ), ), ); @@ -122,15 +122,14 @@ Future main() async { supportedLocales: const [Locale('en'), Locale('fr'), Locale('es')], path: 'assets/translations', fallbackLocale: const Locale('en'), - child: Gecko(indexerEndpoint), + child: const Gecko(), ), ); } } class Gecko extends StatelessWidget { - const Gecko(this.indexerEndpoint, {Key? key}) : super(key: key); - final String? indexerEndpoint; + const Gecko({Key? key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index d5ca4c3..acc7b25 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -5,6 +5,9 @@ const keyInfoPopup = Key('keyInfoPopup'); const keyGoNext = Key('keyGoNext'); const keyCancel = Key('keyCancel'); const keyConfirm = Key('keyConfirm'); +const keyAppBarSearch = Key('keyAppBarSearch'); +const keyAppBarQrcode = Key('keyAppBarQrcode'); +const keyAppBarChest = Key('keyAppBarChest'); // Home const keyParameters = Key('keyParameters'); @@ -28,6 +31,8 @@ const keySetDefaultWallet = Key('keySetDefaultWallet'); const keyDeleteWallet = Key('keyDeleteWallet'); const keyWalletName = Key('keyWalletName'); const keyRenameWallet = Key('keyRenameWallet'); +const keyConfirmIdentity = Key('keyConfirmIdentity'); +const keyEnterIdentityUsername = Key('keyEnterIdentityUsername'); // Chest options const keyShowSeed = Key('keyShowSeed'); @@ -79,7 +84,9 @@ const keySearchField = Key('keySearchField'); const keyConfirmSearch = Key('keyConfirmSearch'); // Unit keys -Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); Key keyTransaction(int keyId) => Key('keyTransaction$keyId'); +Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); Key keySearchResult(String keyId) => Key('keySearchResult$keyId'); Key keySelectDuniterNode(String keyId) => Key('keySelectDuniterNode$keyId'); +Key keyOpenWallet(String keyId) => Key('keyOpenWallet$keyId'); +Key keySelectThisWallet(String keyId) => Key('keySelectThisWallet$keyId'); diff --git a/lib/providers/home.dart b/lib/providers/home.dart index d825863..d939007 100644 --- a/lib/providers/home.dart +++ b/lib/providers/home.dart @@ -11,6 +11,7 @@ import 'package:flutter/services.dart'; import 'dart:async'; import 'package:gecko/globals.dart'; import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/wallets_profiles.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; @@ -148,6 +149,7 @@ class HomeProvider with ChangeNotifier { const Spacer(), const SizedBox(width: 11), IconButton( + key: keyAppBarSearch, iconSize: 40, icon: const Image(image: AssetImage('assets/loupe-noire.png')), onPressed: () { @@ -165,7 +167,7 @@ class HomeProvider with ChangeNotifier { ), const SizedBox(width: 22), const Spacer(), - IconButton( + IconButton(key: keyAppBarQrcode, iconSize: 70, icon: const Image(image: AssetImage('assets/qrcode-scan.png')), onPressed: () async { @@ -178,7 +180,7 @@ class HomeProvider with ChangeNotifier { ), const Spacer(), const SizedBox(width: 15), - IconButton( + IconButton(key: keyAppBarChest, iconSize: 60, icon: const Image(image: AssetImage('assets/wallet.png')), onPressed: () async { diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 6f18f69..9f7e225 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -941,8 +941,7 @@ newKeySig: $newKeySig"""); Future spawnBlock([int number = 1]) async { for (var i = 1; i <= number; i++) { - await sdk.webView! - .evalJavascript('api.rpc.engine.createBlock(true, true)'); + sdk.webView!.evalJavascript('api.rpc.engine.createBlock(true, true)'); } } diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index 1fcac90..f581a8b 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -238,7 +238,7 @@ class WalletOptionsProvider with ChangeNotifier { height: 100, child: Column(children: [ const SizedBox(height: 20), - TextField( + TextField(key: keyEnterIdentityUsername, onChanged: (_) => notifyListeners(), inputFormatters: [ // FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")), @@ -259,7 +259,7 @@ class WalletOptionsProvider with ChangeNotifier { Consumer( builder: (context, wOptions, _) { return TextButton( - key: keyInfoPopup, + key: keyConfirm, child: Text( "validate".tr(), style: TextStyle( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 22544f9..34e47bd 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -132,22 +132,24 @@ class HomeScreen extends StatelessWidget { // sub.nodeConnected = false; // } - HomeProvider homeProvider = - Provider.of(ctx, listen: false); - Connectivity() - .onConnectivityChanged - .listen((ConnectivityResult result) async { - log.d('Network changed: $result'); - if (result == ConnectivityResult.none) { - sub.nodeConnected = false; - await sub.sdk.api.setting.unsubscribeBestNumber(); - homeProvider.changeMessage( - "notConnectedToInternet".tr(), 0); - sub.reload(); - } else { - await sub.connectNode(ctx); - } - }); + // TODO: fix random bad network status on startup + // HomeProvider homeProvider = + // Provider.of(ctx, listen: false); + // Connectivity() + // .onConnectivityChanged + // .listen((ConnectivityResult result) async { + // log.d('Network changed: $result'); + // if (result == ConnectivityResult.none) { + // sub.nodeConnected = false; + // await sub.sdk.api.setting.unsubscribeBestNumber(); + // homeProvider.changeMessage( + // "notConnectedToInternet".tr(), 0); + // sub.reload(); + // } else { + // await sub.connectNode(ctx); + // } + // }); + await sub.connectNode(ctx); } // _duniterIndexer.checkIndexerEndpointBackground(); }); diff --git a/lib/screens/myWallets/choose_wallet.dart b/lib/screens/myWallets/choose_wallet.dart index eb38197..8f4d73a 100644 --- a/lib/screens/myWallets/choose_wallet.dart +++ b/lib/screens/myWallets/choose_wallet.dart @@ -47,6 +47,7 @@ class ChooseWalletScreen extends StatelessWidget { width: 470, height: 70, child: ElevatedButton( + key: keyConfirm, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background @@ -123,6 +124,7 @@ class ChooseWalletScreen extends StatelessWidget { Padding( padding: const EdgeInsets.all(16), child: GestureDetector( + key: keySelectThisWallet(repository.address!), onTap: () { selectedWallet = repository; myWalletProvider.rebuildWidget(); diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index a202abd..a6abfc2 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -292,7 +292,7 @@ class WalletOptions extends StatelessWidget { SizedBox( width: 320, height: 60, - child: ElevatedButton( + child: ElevatedButton(key: keyConfirmIdentity, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index 03ba5e1..cdf307e 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -200,6 +200,7 @@ class WalletsHome extends StatelessWidget { Padding( padding: const EdgeInsets.all(16), child: GestureDetector( + key: keyOpenWallet(repository.address!), onTap: () { walletOptions.getAddress( currentChestNumber, repository.derivation!); diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 45db562..ae13fc7 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -481,7 +481,7 @@ class WalletViewScreen extends StatelessWidget { ), const SizedBox(height: 10), Consumer(builder: (context, sub, _) { - return InkWell( + return InkWell(key: keyChangeChest, onTap: () async { String? pin; if (myWalletProvider.pinCode == '') { From 27e4de7254dcc610edd586590094912f080db37a Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 24 Aug 2022 23:09:56 +0200 Subject: [PATCH 08/28] add coments to importChest test --- integration_test/gecko_complete.dart | 38 ++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index 1a42d4c..0d6723f 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -41,13 +41,10 @@ Future changeNode(WidgetTester tester) async { await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); - // await sleep(tester, 10000); await goKey(tester, keyConnectToEndpoint); await isIconPresent(tester, Icons.add_card_sharp, timeout: const Duration(seconds: 8)); await goBack(tester); - - // await waitFor(tester, 'Vous êtes bien connecté'); } // Customs actions @@ -62,32 +59,63 @@ Future deleteAllWallets(WidgetTester tester) async { } Future restoreChest(WidgetTester tester) async { - await goKey(tester, keyRestoreChest); + // Copy test mnemonic in clipboard Clipboard.setData(const ClipboardData( text: 'pipe paddle ketchup filter life ice feel embody glide quantum ride usage')); + + // Open screen import chest + await goKey(tester, keyRestoreChest); + + // Wait frame stop before continue await tester.pumpAndSettle(); + + // Tap on button to paste mnemonic await goKey(tester, keyPastMnemonic); await tester.pumpAndSettle(); + + // Tap on next button 4 times to skip 3 screen await goKey(tester, keyGoNext); await goKey(tester, keyGoNext); await goKey(tester, keyGoNext); await goKey(tester, keyGoNext); + + // Check if cached password checkbox is checked final isCached = await isIconPresent(tester, Icons.check_box); + + // If not, tap on to cache password if (!isCached) await goKey(tester, keyCachePassword); + + // Enter password await enterText(tester, keyPinForm, 'AAAAA'); + + // Check if string "Accéder à mon coffre" is present in screen await waitFor(tester, 'Accéder à mon coffre'); + + // Go to wallets home await goKey(tester, keyGoWalletsHome); + + // Check if string "ĞD" is present in screen await waitFor(tester, 'ĞD'); - // Test add a new derivation + // Tap on add a new derivation button await addDerivation(tester); + + // Tap on Wallet 5 await goKey(tester, keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); + + // Copy address of Wallet 5 await goKey(tester, keyCopyAddress); + + // Check if string "Cette adresse a été copié" is present in screen await waitFor(tester, 'Cette adresse a été copié'); + + // Pop screen 2 time to go back home screen await goBack(tester); await goBack(tester); + + // Check if string "y'a pas de lézard" is present in screen await waitFor(tester, "y'a pas de lézard"); } From c060c85df873d942fb5ec65d910f8fbad43a0a96 Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 24 Aug 2022 23:59:51 +0200 Subject: [PATCH 09/28] flutter format --- lib/models/widgets_keys.dart | 11 ++++++----- lib/providers/home.dart | 6 ++++-- lib/providers/wallet_options.dart | 3 ++- lib/screens/myWallets/wallet_options.dart | 3 ++- lib/screens/wallet_view.dart | 3 ++- 5 files changed, 16 insertions(+), 10 deletions(-) diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index acc7b25..58b3935 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -83,10 +83,11 @@ const keyGoWalletsHome = Key('keyGoWalletsHome'); const keySearchField = Key('keySearchField'); const keyConfirmSearch = Key('keyConfirmSearch'); -// Unit keys +// Items keys Key keyTransaction(int keyId) => Key('keyTransaction$keyId'); Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); -Key keySearchResult(String keyId) => Key('keySearchResult$keyId'); -Key keySelectDuniterNode(String keyId) => Key('keySelectDuniterNode$keyId'); -Key keyOpenWallet(String keyId) => Key('keyOpenWallet$keyId'); -Key keySelectThisWallet(String keyId) => Key('keySelectThisWallet$keyId'); +Key keySearchResult(String address) => Key('keySearchResult$address'); +Key keySelectDuniterNode(String endpoint) => + Key('keySelectDuniterNode$endpoint'); +Key keyOpenWallet(String address) => Key('keyOpenWallet$address'); +Key keySelectThisWallet(String address) => Key('keySelectThisWallet$address'); diff --git a/lib/providers/home.dart b/lib/providers/home.dart index d939007..fe5102f 100644 --- a/lib/providers/home.dart +++ b/lib/providers/home.dart @@ -167,7 +167,8 @@ class HomeProvider with ChangeNotifier { ), const SizedBox(width: 22), const Spacer(), - IconButton(key: keyAppBarQrcode, + IconButton( + key: keyAppBarQrcode, iconSize: 70, icon: const Image(image: AssetImage('assets/qrcode-scan.png')), onPressed: () async { @@ -180,7 +181,8 @@ class HomeProvider with ChangeNotifier { ), const Spacer(), const SizedBox(width: 15), - IconButton(key: keyAppBarChest, + IconButton( + key: keyAppBarChest, iconSize: 60, icon: const Image(image: AssetImage('assets/wallet.png')), onPressed: () async { diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index f581a8b..ac2f106 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -238,7 +238,8 @@ class WalletOptionsProvider with ChangeNotifier { height: 100, child: Column(children: [ const SizedBox(height: 20), - TextField(key: keyEnterIdentityUsername, + TextField( + key: keyEnterIdentityUsername, onChanged: (_) => notifyListeners(), inputFormatters: [ // FilteringTextInputFormatter.allow(RegExp("[0-9a-zA-Z]")), diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index a6abfc2..de5e74e 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -292,7 +292,8 @@ class WalletOptions extends StatelessWidget { SizedBox( width: 320, height: 60, - child: ElevatedButton(key: keyConfirmIdentity, + child: ElevatedButton( + key: keyConfirmIdentity, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index ae13fc7..29b6db6 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -481,7 +481,8 @@ class WalletViewScreen extends StatelessWidget { ), const SizedBox(height: 10), Consumer(builder: (context, sub, _) { - return InkWell(key: keyChangeChest, + return InkWell( + key: keyChangeChest, onTap: () async { String? pin; if (myWalletProvider.pinCode == '') { From 05f41e16a90bb5e2faf7b5981d7411bf3113f8bc Mon Sep 17 00:00:00 2001 From: poka Date: Thu, 25 Aug 2022 00:26:04 +0200 Subject: [PATCH 10/28] improve test speed --- integration_test/gecko_complete.dart | 17 +++++++------- integration_test/tests_utility.dart | 15 ++++++++---- lib/screens/home.dart | 34 ++++++++++++++-------------- 3 files changed, 36 insertions(+), 30 deletions(-) diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index 0d6723f..07e43c0 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -72,7 +72,6 @@ Future restoreChest(WidgetTester tester) async { // Tap on button to paste mnemonic await goKey(tester, keyPastMnemonic); - await tester.pumpAndSettle(); // Tap on next button 4 times to skip 3 screen await goKey(tester, keyGoNext); @@ -84,16 +83,16 @@ Future restoreChest(WidgetTester tester) async { final isCached = await isIconPresent(tester, Icons.check_box); // If not, tap on to cache password - if (!isCached) await goKey(tester, keyCachePassword); + if (!isCached) await goKey(tester, keyCachePassword, duration: 0); // Enter password - await enterText(tester, keyPinForm, 'AAAAA'); + await enterText(tester, keyPinForm, 'AAAAA', 0); // Check if string "Accéder à mon coffre" is present in screen await waitFor(tester, 'Accéder à mon coffre'); // Go to wallets home - await goKey(tester, keyGoWalletsHome); + await goKey(tester, keyGoWalletsHome, duration: 0); // Check if string "ĞD" is present in screen await waitFor(tester, 'ĞD'); @@ -138,7 +137,7 @@ Future payTest2(WidgetTester tester) async { await spawnBlock(tester, keyCloseTransactionScreen); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen); + await goKey(tester, keyCloseTransactionScreen, duration: 0); await waitFor(tester, '12.14'); await spawnBlock(tester, keyViewActivity); await waitFor(tester, '9.14'); @@ -155,7 +154,7 @@ Future certifyTest5(WidgetTester tester) async { // await sleep(tester); await goKey(tester, keyCertify); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyViewActivity); + await spawnBlock(tester, keyViewActivity, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Identité créée'); @@ -168,7 +167,7 @@ Future certifyTest5(WidgetTester tester) async { await goKey(tester, keyConfirmIdentity); await enterText(tester, keyEnterIdentityUsername, 'test5'); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyCloseTransactionScreen); + await spawnBlock(tester, keyCloseTransactionScreen, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Identité confirmée'); @@ -192,7 +191,7 @@ Future certifyTest5(WidgetTester tester) async { // Certify with test2 account await goKey(tester, keyCertify); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyViewActivity); + await spawnBlock(tester, keyViewActivity, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, '2'); @@ -208,7 +207,7 @@ Future certifyTest5(WidgetTester tester) async { // Certify with test3 account await goKey(tester, keyCertify); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyViewActivity); + await spawnBlock(tester, keyViewActivity, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Vous devez attendre'); diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 50130a6..e3d31a5 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -12,7 +12,9 @@ Future sleep(WidgetTester tester, [int time = 1000]) async { Future goKey(WidgetTester tester, Key buttonKey, {Finder? customFinder, int duration = 100, bool selectLast = false}) async { - await tester.pumpAndSettle(Duration(milliseconds: duration)); + if (duration != 0) { + await tester.pumpAndSettle(Duration(milliseconds: duration)); + } final Finder finder = customFinder ?? find.byKey(buttonKey); log.d('INTEGRATION TEST: Tap on ${finder.description}}'); await tester.tap(selectLast ? finder.last : finder); @@ -28,7 +30,9 @@ Future goBack(WidgetTester tester) async { Future enterText(WidgetTester tester, Key fieldKey, String textIn, [int duration = 200]) async { - await tester.pumpAndSettle(Duration(milliseconds: duration)); + if (duration != 0) { + await tester.pumpAndSettle(Duration(milliseconds: duration)); + } log.d('INTEGRATION TEST: Enter text: $textIn'); await tester.enterText(find.byKey(fieldKey), textIn); } @@ -73,8 +77,11 @@ Future isIconPresent(WidgetTester tester, IconData icon, return finder.evaluate().isEmpty ? false : true; } -Future spawnBlock(WidgetTester tester, Key customKey, [int number = 1]) async { - await sleep(tester, 1000); +Future spawnBlock(WidgetTester tester, Key customKey, + {int number = 1, int duration = 200}) async { + if (duration != 0) { + await sleep(tester, duration); + } final BuildContext context = tester.element(find.byKey(customKey)); SubstrateSdk sub = Provider.of(context, listen: false); sub.spawnBlock(number); diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 34e47bd..8850781 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -133,23 +133,23 @@ class HomeScreen extends StatelessWidget { // } // TODO: fix random bad network status on startup - // HomeProvider homeProvider = - // Provider.of(ctx, listen: false); - // Connectivity() - // .onConnectivityChanged - // .listen((ConnectivityResult result) async { - // log.d('Network changed: $result'); - // if (result == ConnectivityResult.none) { - // sub.nodeConnected = false; - // await sub.sdk.api.setting.unsubscribeBestNumber(); - // homeProvider.changeMessage( - // "notConnectedToInternet".tr(), 0); - // sub.reload(); - // } else { - // await sub.connectNode(ctx); - // } - // }); - await sub.connectNode(ctx); + HomeProvider homeProvider = + Provider.of(ctx, listen: false); + Connectivity() + .onConnectivityChanged + .listen((ConnectivityResult result) async { + log.d('Network changed: $result'); + if (result == ConnectivityResult.none) { + sub.nodeConnected = false; + await sub.sdk.api.setting.unsubscribeBestNumber(); + homeProvider.changeMessage( + "notConnectedToInternet".tr(), 0); + sub.reload(); + } else { + await sub.connectNode(ctx); + } + }); + // await sub.connectNode(ctx); } // _duniterIndexer.checkIndexerEndpointBackground(); }); From aa7bc7464500dd83abc991ac142e94d6dc32e32c Mon Sep 17 00:00:00 2001 From: poka Date: Sat, 27 Aug 2022 00:31:19 +0200 Subject: [PATCH 11/28] add .env to git repository with default value --- .env | 1 + .gitignore | 1 - integration_test/gecko_complete.dart | 13 ++++++------- integration_test/launch_test.sh | 3 +++ integration_test/tests_utility.dart | 2 +- 5 files changed, 11 insertions(+), 9 deletions(-) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..797c39f --- /dev/null +++ b/.env @@ -0,0 +1 @@ +ip_address=127.0.0.1 diff --git a/.gitignore b/.gitignore index b021e4e..e903697 100644 --- a/.gitignore +++ b/.gitignore @@ -56,5 +56,4 @@ AppDir/ appimage-builder-cache/ AppImageBuilder.yml android/app/build.gradle -.env integration_test/duniter/data/chains/ \ No newline at end of file diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index 07e43c0..7c7c3a7 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -18,16 +18,16 @@ void main() { // Change Duniter endpoint to local await changeNode(tester); - // Delete all existing chests + // Delete all existing chests is exists await deleteAllWallets(tester); - // Restore a chest + // Restore the test chest await restoreChest(tester); // Execute a transaction to test2 await payTest2(tester); - // Certify test5 account with 3 account to become member + // Certify test5 account with 3 accounts to become member await certifyTest5(tester); }); } @@ -47,7 +47,6 @@ Future changeNode(WidgetTester tester) async { await goBack(tester); } -// Customs actions Future deleteAllWallets(WidgetTester tester) async { if (await isPresent(tester, 'Rechercher')) { await goKey(tester, keyDrawerMenu); @@ -133,7 +132,6 @@ Future payTest2(WidgetTester tester) async { await goKey(tester, keyPay); await enterText(tester, keyAmountField, '12.14'); await goKey(tester, keyConfirmPayment); - // await sleep(tester); await spawnBlock(tester, keyCloseTransactionScreen); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); @@ -150,8 +148,6 @@ Future addDerivation(WidgetTester tester) async { Future certifyTest5(WidgetTester tester) async { // Create identity with Test1 account - // await spawnBlock(tester, keyViewActivity, 5); - // await sleep(tester); await goKey(tester, keyCertify); await goKey(tester, keyConfirm); await spawnBlock(tester, keyViewActivity, duration: 500); @@ -171,12 +167,15 @@ Future certifyTest5(WidgetTester tester) async { await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Identité confirmée'); + + // Set wallet 2 as default wallet await goBack(tester); await goKey(tester, keyOpenWallet('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb')); await goKey(tester, keySetDefaultWallet); await waitFor(tester, 'Ce portefeuille est celui par defaut'); + // Search Wallet 5 again await goKey(tester, keyAppBarSearch); final addressToSearch = (await Clipboard.getData('text/plain'))!.text; final endAddress = addressToSearch!.substring(addressToSearch.length - 6); diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh index aa72d85..c4a4b87 100755 --- a/integration_test/launch_test.sh +++ b/integration_test/launch_test.sh @@ -21,6 +21,9 @@ cd ../.. # Start integration test flutter test integration_test/$testName.dart +# Reset .env +echo "ip_address=127.0.0.1" > .env + # Stop Duniter cd integration_test/duniter docker-compose down diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index e3d31a5..260f391 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -4,7 +4,7 @@ import 'package:gecko/globals.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; -// CUSTOM METHODS +// CUSTOM FUNCTIONS Future sleep(WidgetTester tester, [int time = 1000]) async { await Future.delayed(Duration(milliseconds: time)); From 376149460655756e75761ccfc16465d5637d364c Mon Sep 17 00:00:00 2001 From: poka Date: Sat, 27 Aug 2022 05:43:43 +0200 Subject: [PATCH 12/28] refactor tests env --- assets/translations/fr.json | 2 +- integration_test/cert_state.dart | 59 ++++++++++++ integration_test/gecko_complete.dart | 124 +++----------------------- integration_test/general_actions.dart | 96 ++++++++++++++++++++ integration_test/tests_utility.dart | 76 +++++++++++++--- lib/providers/substrate_sdk.dart | 16 ++-- lib/screens/wallet_view.dart | 5 +- 7 files changed, 247 insertions(+), 131 deletions(-) create mode 100644 integration_test/cert_state.dart create mode 100644 integration_test/general_actions.dart diff --git a/assets/translations/fr.json b/assets/translations/fr.json index 57056c4..bfe26e6 100644 --- a/assets/translations/fr.json +++ b/assets/translations/fr.json @@ -148,7 +148,7 @@ "seeAWallet": "Voir un portefeuille", "mustWaitXBeforeCertify": "Vous devez attendre\n{} avant\nde pouvoir certifier", "mustConfirmHisIdentity": "Cette personne doit confirmer\nson identité avant de pouvoir\nêtre certifié", - "canRenewCertInX": "Vous pourrez renouveller\ncette certification\ndans {}", + "canRenewCertInX": "Vous pourrez renouveler\ncette certification\ndans {}", "executeATransfer": "Effectuer un virement", "executeTheTransfer": "Effectuer le virement", "doATransfer": "Faire un\nvirement", diff --git a/integration_test/cert_state.dart b/integration_test/cert_state.dart new file mode 100644 index 0000000..d3e589a --- /dev/null +++ b/integration_test/cert_state.dart @@ -0,0 +1,59 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:integration_test/integration_test.dart'; +import 'package:gecko/main.dart' as app; +import 'general_actions.dart'; +import 'tests_utility.dart'; + +void main() { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + + testWidgets('Gecko complete', (tester) async { + app.main(); + await tester.pumpAndSettle(const Duration(seconds: 1)); + + // Change Duniter endpoint to local + await changeNode(tester); + + // Delete all existing chests is exists + await deleteAllWallets(tester); + + // Restore the test chest + await restoreChest(tester); + + // Go wallet 5 view + await goKey(tester, keyOpenSearch); + await enterText(tester, keySearchField, test5.address); + await goKey(tester, keyConfirmSearch); + await waitFor(tester, test5.shortAddress()); + await goKey(tester, keySearchResult(test5.address)); + await waitFor(tester, 'Certifier'); + await waitFor(tester, 'Vous devez ', reverse: true); + await waitFor(tester, 'Vous pourrez renouveler ', reverse: true); + + // Background pay 25 + await pay(tester, + fromAddress: test1.address, destAddress: test5.address, amount: 25); + await waitFor(tester, '25.0 $currencyName'); + await spawnBlock(tester); + await waitFor(tester, '22.0 $currencyName'); + await certify(tester, + fromAddress: test1.address, destAddress: test5.address); + await waitFor(tester, '1', exactMatch: true); + await confirmIdentity(tester, fromAddress: test5.address, name: test5.name); + await spawnBlock(tester, number: 10); + await certify(tester, + fromAddress: test2.address, destAddress: test5.address); + await waitFor(tester, '2', exactMatch: true); + await certify(tester, + fromAddress: test3.address, destAddress: test5.address); + await waitFor(tester, '3', exactMatch: true); + await certify(tester, + fromAddress: test4.address, destAddress: test5.address); + await waitFor(tester, '4', exactMatch: true); + await pay(tester, + fromAddress: test2.address, destAddress: test5.address, amount: 40); + await waitFor(tester, '62.0 $currencyName'); + }); +} diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index 7c7c3a7..320577a 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -1,11 +1,9 @@ -import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; import 'package:gecko/main.dart' as app; +import 'general_actions.dart'; import 'tests_utility.dart'; void main() { @@ -32,97 +30,12 @@ void main() { }); } -Future changeNode(WidgetTester tester) async { - final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; - log.d('ip address: $ipAddress'); - - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); - await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); - await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); - await goKey(tester, keyConnectToEndpoint); - await isIconPresent(tester, Icons.add_card_sharp, - timeout: const Duration(seconds: 8)); - await goBack(tester); -} - -Future deleteAllWallets(WidgetTester tester) async { - if (await isPresent(tester, 'Rechercher')) { - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keyDeleteAllWallets); - await goKey(tester, keyConfirm); - await tester.pumpAndSettle(); - } -} - -Future restoreChest(WidgetTester tester) async { - // Copy test mnemonic in clipboard - Clipboard.setData(const ClipboardData( - text: - 'pipe paddle ketchup filter life ice feel embody glide quantum ride usage')); - - // Open screen import chest - await goKey(tester, keyRestoreChest); - - // Wait frame stop before continue - await tester.pumpAndSettle(); - - // Tap on button to paste mnemonic - await goKey(tester, keyPastMnemonic); - - // Tap on next button 4 times to skip 3 screen - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - - // Check if cached password checkbox is checked - final isCached = await isIconPresent(tester, Icons.check_box); - - // If not, tap on to cache password - if (!isCached) await goKey(tester, keyCachePassword, duration: 0); - - // Enter password - await enterText(tester, keyPinForm, 'AAAAA', 0); - - // Check if string "Accéder à mon coffre" is present in screen - await waitFor(tester, 'Accéder à mon coffre'); - - // Go to wallets home - await goKey(tester, keyGoWalletsHome, duration: 0); - - // Check if string "ĞD" is present in screen - await waitFor(tester, 'ĞD'); - - // Tap on add a new derivation button - await addDerivation(tester); - - // Tap on Wallet 5 - await goKey(tester, - keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); - - // Copy address of Wallet 5 - await goKey(tester, keyCopyAddress); - - // Check if string "Cette adresse a été copié" is present in screen - await waitFor(tester, 'Cette adresse a été copié'); - - // Pop screen 2 time to go back home screen - await goBack(tester); - await goBack(tester); - - // Check if string "y'a pas de lézard" is present in screen - await waitFor(tester, "y'a pas de lézard"); -} - Future payTest2(WidgetTester tester) async { await waitFor(tester, 'Rechercher'); await goKey(tester, keyOpenSearch); final addressToSearch = (await Clipboard.getData('text/plain'))!.text; final endAddress = addressToSearch!.substring(addressToSearch.length - 6); - expect(addressToSearch, '5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R'); + expect(addressToSearch, test5.address); await enterText(tester, keySearchField, addressToSearch); await goKey(tester, keyConfirmSearch); await waitFor(tester, endAddress); @@ -132,46 +45,39 @@ Future payTest2(WidgetTester tester) async { await goKey(tester, keyPay); await enterText(tester, keyAmountField, '12.14'); await goKey(tester, keyConfirmPayment); - await spawnBlock(tester, keyCloseTransactionScreen); + await spawnBlock(tester); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen, duration: 0); await waitFor(tester, '12.14'); - await spawnBlock(tester, keyViewActivity); + await spawnBlock(tester); await waitFor(tester, '9.14'); } -Future addDerivation(WidgetTester tester) async { - await goKey(tester, keyAddDerivation); - await waitFor(tester, 'Portefeuille 5'); -} - Future certifyTest5(WidgetTester tester) async { // Create identity with Test1 account await goKey(tester, keyCertify); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyViewActivity, duration: 500); + await spawnBlock(tester, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Identité créée'); // Confirm Identity Test5 await goKey(tester, keyAppBarChest, duration: 300); - await goKey(tester, - keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); + await goKey(tester, keyOpenWallet(test5.address)); await goKey(tester, keyCopyAddress); await goKey(tester, keyConfirmIdentity); - await enterText(tester, keyEnterIdentityUsername, 'test5'); + await enterText(tester, keyEnterIdentityUsername, test5.name); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyCloseTransactionScreen, duration: 500); + await spawnBlock(tester, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Identité confirmée'); // Set wallet 2 as default wallet await goBack(tester); - await goKey(tester, - keyOpenWallet('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb')); + await goKey(tester, keyOpenWallet(test2.address)); await goKey(tester, keySetDefaultWallet); await waitFor(tester, 'Ce portefeuille est celui par defaut'); @@ -179,7 +85,7 @@ Future certifyTest5(WidgetTester tester) async { await goKey(tester, keyAppBarSearch); final addressToSearch = (await Clipboard.getData('text/plain'))!.text; final endAddress = addressToSearch!.substring(addressToSearch.length - 6); - expect(addressToSearch, '5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R'); + expect(addressToSearch, test5.address); await enterText(tester, keySearchField, addressToSearch); await goKey(tester, keyConfirmSearch); await waitFor(tester, endAddress); @@ -190,7 +96,7 @@ Future certifyTest5(WidgetTester tester) async { // Certify with test2 account await goKey(tester, keyCertify); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyViewActivity, duration: 500); + await spawnBlock(tester, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, '2'); @@ -198,22 +104,20 @@ Future certifyTest5(WidgetTester tester) async { // Change default wallet to test3 await goKey(tester, keyPay); await goKey(tester, keyChangeChest); - await goKey(tester, - keySelectThisWallet('5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p')); + await goKey(tester, keySelectThisWallet(test3.address)); await goKey(tester, keyConfirm); await sleep(tester); // Certify with test3 account await goKey(tester, keyCertify); await goKey(tester, keyConfirm); - await spawnBlock(tester, keyViewActivity, duration: 500); + await spawnBlock(tester, duration: 500); await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); await goKey(tester, keyCloseTransactionScreen); await waitFor(tester, 'Vous devez attendre'); // Check if test5 is member await goKey(tester, keyAppBarChest, duration: 300); - await goKey(tester, - keyOpenWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R')); + await goKey(tester, keyOpenWallet(test5.address)); await waitFor(tester, 'Membre validé !'); } diff --git a/integration_test/general_actions.dart b/integration_test/general_actions.dart new file mode 100644 index 0000000..4ad5057 --- /dev/null +++ b/integration_test/general_actions.dart @@ -0,0 +1,96 @@ +import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'tests_utility.dart'; + +// GENERAL ACTIONS + +Future changeNode(WidgetTester tester) async { + final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; + log.d('ip address: $ipAddress'); + + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); + await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); + await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); + await goKey(tester, keyConnectToEndpoint); + await isIconPresent(tester, Icons.add_card_sharp, + timeout: const Duration(seconds: 8)); + await goBack(tester); +} + +Future deleteAllWallets(WidgetTester tester) async { + if (await isPresent(tester, 'Rechercher')) { + await goKey(tester, keyDrawerMenu); + await goKey(tester, keyParameters); + await goKey(tester, keyDeleteAllWallets); + await goKey(tester, keyConfirm); + await tester.pumpAndSettle(); + } +} + +Future restoreChest(WidgetTester tester) async { + // Copy test mnemonic in clipboard + Clipboard.setData(const ClipboardData(text: testMnemonic)); + + // Open screen import chest + await goKey(tester, keyRestoreChest); + + // Wait frame stop before continue + await tester.pumpAndSettle(); + + // Tap on button to paste mnemonic + await goKey(tester, keyPastMnemonic); + + // Tap on next button 4 times to skip 3 screen + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + await goKey(tester, keyGoNext); + + // Check if cached password checkbox is checked + final isCached = await isIconPresent(tester, Icons.check_box); + + // If not, tap on to cache password + if (!isCached) await goKey(tester, keyCachePassword, duration: 0); + + // Enter password + await enterText(tester, keyPinForm, 'AAAAA', 0); + + // Check if string "Accéder à mon coffre" is present in screen + await waitFor(tester, 'Accéder à mon coffre'); + + // Go to wallets home + await goKey(tester, keyGoWalletsHome, duration: 0); + + // Check if string "ĞD" is present in screen + await waitFor(tester, 'ĞD'); + + // Tap on add a new derivation button + await addDerivation(tester); + + // Tap on Wallet 5 + await goKey(tester, keyOpenWallet(test5.address)); + + // Copy address of Wallet 5 + await goKey(tester, keyCopyAddress); + + // Check if string "Cette adresse a été copié" is present in screen + await waitFor(tester, 'Cette adresse a été copié'); + + // Pop screen 2 time to go back home screen + await goBack(tester); + await goBack(tester); + + // Check if string "y'a pas de lézard" is present in screen + await waitFor(tester, "y'a pas de lézard"); +} + +Future addDerivation(WidgetTester tester) async { + await goKey(tester, keyAddDerivation); + await waitFor(tester, 'Portefeuille 5'); +} diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 260f391..39785c3 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -4,6 +4,28 @@ import 'package:gecko/globals.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; +final sub = Provider.of(homeContext, listen: false); + +// TEST WALLETS CONSTS +const testMnemonic = + 'pipe paddle ketchup filter life ice feel embody glide quantum ride usage'; +final test1 = + TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test1'); +final test2 = + TestWallet('5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb', 'test2'); +final test3 = + TestWallet('5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p', 'test3'); +final test4 = + TestWallet('5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5', 'test4'); +final test5 = + TestWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R', 'test5'); +// final test6 = +// TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test6'); +// final test7 = +// TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test7'); +// final test8 = +// TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test8'); + // CUSTOM FUNCTIONS Future sleep(WidgetTester tester, [int time = 1000]) async { @@ -37,14 +59,13 @@ Future enterText(WidgetTester tester, Key fieldKey, String textIn, await tester.enterText(find.byKey(fieldKey), textIn); } -Future waitFor( - WidgetTester tester, - String text, { - Duration timeout = const Duration(seconds: 5), -}) async { +Future waitFor(WidgetTester tester, String text, + {Duration timeout = const Duration(seconds: 5), + bool reverse = false, + bool exactMatch = false}) async { final end = DateTime.now().add(timeout); - Finder finder = find.textContaining(text); + Finder finder = exactMatch ? find.text(text) : find.textContaining(text); log.d('INTEGRATION TEST: Wait for: $text'); do { @@ -54,7 +75,7 @@ Future waitFor( await tester.pumpAndSettle(); await Future.delayed(const Duration(milliseconds: 100)); - } while (finder.evaluate().isEmpty); + } while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty); } // Test if text is visible on screen, return a boolean @@ -77,13 +98,48 @@ Future isIconPresent(WidgetTester tester, IconData icon, return finder.evaluate().isEmpty ? false : true; } -Future spawnBlock(WidgetTester tester, Key customKey, +Future spawnBlock(WidgetTester tester, {int number = 1, int duration = 200}) async { if (duration != 0) { await sleep(tester, duration); } - final BuildContext context = tester.element(find.byKey(customKey)); - SubstrateSdk sub = Provider.of(context, listen: false); sub.spawnBlock(number); await sleep(tester, 500); } + +Future pay(WidgetTester tester, + {required String fromAddress, + required String destAddress, + required double amount}) async { + sub.pay( + fromAddress: fromAddress, + destAddress: destAddress, + amount: amount, + password: 'AAAAA'); + spawnBlock(tester, duration: 500); + await sleep(tester, 500); +} + +Future certify(WidgetTester tester, + {required String fromAddress, required String destAddress}) async { + sub.certify(fromAddress, destAddress, 'AAAAA'); + spawnBlock(tester, duration: 500); + await sleep(tester, 500); +} + +Future confirmIdentity(WidgetTester tester, + {required String fromAddress, required String name}) async { + sub.confirmIdentity(fromAddress, name, 'AAAAA'); + spawnBlock(tester, duration: 500); + await sleep(tester, 500); +} + +class TestWallet { + String address; + String name; + + TestWallet(this.address, this.name); + + endAddress() => address.substring(address.length - 6); + shortAddress() => getShortPubkey(address); +} diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 9f7e225..ccd81b1 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -696,14 +696,14 @@ class SubstrateSdk with ChangeNotifier { } Future certify( - String fromAddress, String password, String toAddress) async { + String fromAddress, String destAddress, String password) async { transactionStatus = ''; final myIdtyStatus = await idtyStatus(fromAddress); - final toIdtyStatus = await idtyStatus(toAddress); + final toIdtyStatus = await idtyStatus(destAddress); final fromIndex = await _getIdentityIndexOf(fromAddress); - final toIndex = await _getIdentityIndexOf(toAddress); + final toIndex = await _getIdentityIndexOf(destAddress); if (myIdtyStatus != 'Validated') { transactionStatus = 'notMember'; @@ -716,7 +716,7 @@ class SubstrateSdk with ChangeNotifier { List txOptions = []; String? rawParams; - final toCerts = await getCerts(toAddress); + final toCerts = await getCerts(destAddress); // log.d('debug: ${currencyParameters['minCertForMembership']}'); @@ -726,7 +726,7 @@ class SubstrateSdk with ChangeNotifier { 'createIdentity', sender, ); - txOptions = [toAddress]; + txOptions = [destAddress]; } else if (toIdtyStatus == 'Validated' || toIdtyStatus == 'ConfirmedByOwner') { if (toCerts[0] >= currencyParameters['minCertForMembership']! - 1 && @@ -776,11 +776,11 @@ class SubstrateSdk with ChangeNotifier { Future confirmIdentity( String fromAddress, String name, String password) async { - log.d('me: ${keyring.current.address!}'); + final fromPubkey = await sdk.api.account.decodeAddress([fromAddress]); final sender = TxSenderData( - keyring.current.address, - keyring.current.pubKey, + fromAddress, + fromPubkey!.keys.first, ); final txInfo = TxInfoData( diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 29b6db6..d02757b 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -246,8 +246,9 @@ class WalletViewScreen extends StatelessWidget { final acc = sub.getCurrentWallet(); sub.certify( acc.address!, - pin ?? myWalletProvider.pinCode, - walletViewProvider.address!); + walletViewProvider.address!, + pin ?? + myWalletProvider.pinCode); Navigator.push( context, From 18743c871bde532a964a07d4797ba22d6f004949 Mon Sep 17 00:00:00 2001 From: poka Date: Sat, 27 Aug 2022 23:26:37 +0200 Subject: [PATCH 13/28] fix: set good sender for cert action --- lib/providers/substrate_sdk.dart | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index ccd81b1..d0511df 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -80,10 +80,11 @@ class SubstrateSdk with ChangeNotifier { [null])[0]; } - TxSenderData _setSender() { + Future _setSender(String address) async { + final fromPubkey = await sdk.api.account.decodeAddress([address]); return TxSenderData( - keyring.current.address, - keyring.current.pubKey, + address, + fromPubkey!.keys.first, ); } @@ -711,7 +712,7 @@ class SubstrateSdk with ChangeNotifier { return 'notMember'; } - final sender = _setSender(); + final sender = await _setSender(fromAddress); TxInfoData txInfo; List txOptions = []; String? rawParams; @@ -941,7 +942,8 @@ newKeySig: $newKeySig"""); Future spawnBlock([int number = 1]) async { for (var i = 1; i <= number; i++) { - sdk.webView!.evalJavascript('api.rpc.engine.createBlock(true, true)'); + await sdk.webView! + .evalJavascript('api.rpc.engine.createBlock(true, true)'); } } From 525c375c71bc5cd2a7e3d1e9137a4c42e1d7a9b6 Mon Sep 17 00:00:00 2001 From: poka Date: Sat, 27 Aug 2022 23:27:02 +0200 Subject: [PATCH 14/28] add test: certs state on wallet view --- integration_test/cert_state.dart | 21 +++++++++++++++++++-- integration_test/tests_utility.dart | 15 +++++++++------ 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/integration_test/cert_state.dart b/integration_test/cert_state.dart index d3e589a..2ecdb18 100644 --- a/integration_test/cert_state.dart +++ b/integration_test/cert_state.dart @@ -32,6 +32,7 @@ void main() { await waitFor(tester, 'Vous devez ', reverse: true); await waitFor(tester, 'Vous pourrez renouveler ', reverse: true); + // await spawnBlock(tester, number: 10); // Background pay 25 await pay(tester, fromAddress: test1.address, destAddress: test5.address, amount: 25); @@ -42,9 +43,24 @@ void main() { fromAddress: test1.address, destAddress: test5.address); await waitFor(tester, '1', exactMatch: true); await confirmIdentity(tester, fromAddress: test5.address, name: test5.name); - await spawnBlock(tester, number: 10); await certify(tester, fromAddress: test2.address, destAddress: test5.address); + + // // Change default wallet to test3 + // await goKey(tester, keyPay); + // await goKey(tester, keyChangeChest); + // await goKey(tester, keySelectThisWallet(test2.address)); + // await goKey(tester, keyConfirm); + // await sleep(tester); + + // // Certify with test3 account + // await goKey(tester, keyCertify); + // await goKey(tester, keyConfirm); + // await spawnBlock(tester, duration: 500); + // await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); + // await goKey(tester, keyCloseTransactionScreen); + // await waitFor(tester, 'Vous devez attendre'); + await waitFor(tester, '2', exactMatch: true); await certify(tester, fromAddress: test3.address, destAddress: test5.address); @@ -54,6 +70,7 @@ void main() { await waitFor(tester, '4', exactMatch: true); await pay(tester, fromAddress: test2.address, destAddress: test5.address, amount: 40); - await waitFor(tester, '62.0 $currencyName'); + await waitFor(tester, '61.99 $currencyName'); + await spawnBlock(tester, until: 25); }); } diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 39785c3..5c5a410 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -99,12 +99,15 @@ Future isIconPresent(WidgetTester tester, IconData icon, } Future spawnBlock(WidgetTester tester, - {int number = 1, int duration = 200}) async { + {int number = 1, int duration = 200, int? until}) async { if (duration != 0) { await sleep(tester, duration); } - sub.spawnBlock(number); - await sleep(tester, 500); + if (until != null) { + number = until - sub.blocNumber; + } + await sub.spawnBlock(number); + await sleep(tester, 200); } Future pay(WidgetTester tester, @@ -116,21 +119,21 @@ Future pay(WidgetTester tester, destAddress: destAddress, amount: amount, password: 'AAAAA'); - spawnBlock(tester, duration: 500); + await spawnBlock(tester); await sleep(tester, 500); } Future certify(WidgetTester tester, {required String fromAddress, required String destAddress}) async { sub.certify(fromAddress, destAddress, 'AAAAA'); - spawnBlock(tester, duration: 500); + await spawnBlock(tester); await sleep(tester, 500); } Future confirmIdentity(WidgetTester tester, {required String fromAddress, required String name}) async { sub.confirmIdentity(fromAddress, name, 'AAAAA'); - spawnBlock(tester, duration: 500); + await spawnBlock(tester); await sleep(tester, 500); } From 03ab85a28237d6407a846dbcd62411981e677057 Mon Sep 17 00:00:00 2001 From: poka Date: Sun, 28 Aug 2022 05:08:41 +0200 Subject: [PATCH 15/28] refactor test utility; add ud creation state test --- integration_test/cert_state.dart | 97 ++++------ .../duniter/data/gecko_tests.json | 4 +- integration_test/gecko_complete.dart | 170 ++++++++++-------- integration_test/general_actions.dart | 91 +++++----- integration_test/launch_test.sh | 6 +- integration_test/tests_utility.dart | 141 ++++++++++++--- integration_test/ud_creation_state.dart | 29 +++ lib/providers/substrate_sdk.dart | 7 +- lib/screens/myWallets/wallet_options.dart | 4 + lib/screens/wallet_view.dart | 5 +- 10 files changed, 344 insertions(+), 210 deletions(-) create mode 100644 integration_test/ud_creation_state.dart diff --git a/integration_test/cert_state.dart b/integration_test/cert_state.dart index 2ecdb18..bbfe692 100644 --- a/integration_test/cert_state.dart +++ b/integration_test/cert_state.dart @@ -1,76 +1,55 @@ +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:gecko/main.dart' as app; import 'general_actions.dart'; import 'tests_utility.dart'; -void main() { +void main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(); - testWidgets('Gecko complete', (tester) async { - app.main(); - await tester.pumpAndSettle(const Duration(seconds: 1)); + testWidgets('Gecko complete', (testerLoc) async { + tester = testerLoc; + // Connect local node and import test chest in background + await fastStart(); - // Change Duniter endpoint to local - await changeNode(tester); - - // Delete all existing chests is exists - await deleteAllWallets(tester); - - // Restore the test chest - await restoreChest(tester); + // Open chest + await firstOpenChest(); + await goBack(); // Go wallet 5 view - await goKey(tester, keyOpenSearch); - await enterText(tester, keySearchField, test5.address); - await goKey(tester, keyConfirmSearch); - await waitFor(tester, test5.shortAddress()); - await goKey(tester, keySearchResult(test5.address)); - await waitFor(tester, 'Certifier'); - await waitFor(tester, 'Vous devez ', reverse: true); - await waitFor(tester, 'Vous pourrez renouveler ', reverse: true); + await goKey(keyOpenSearch); + await enterText(keySearchField, test5.address); + await goKey(keyConfirmSearch); + await waitFor(test5.shortAddress()); + await goKey(keySearchResult(test5.address)); + await waitFor('Certifier'); + await waitFor('Vous devez ', reverse: true); + await waitFor('Vous pourrez renouveler ', reverse: true); - // await spawnBlock(tester, number: 10); // Background pay 25 - await pay(tester, + await bkPay( fromAddress: test1.address, destAddress: test5.address, amount: 25); - await waitFor(tester, '25.0 $currencyName'); - await spawnBlock(tester); - await waitFor(tester, '22.0 $currencyName'); - await certify(tester, - fromAddress: test1.address, destAddress: test5.address); - await waitFor(tester, '1', exactMatch: true); - await confirmIdentity(tester, fromAddress: test5.address, name: test5.name); - await certify(tester, - fromAddress: test2.address, destAddress: test5.address); - - // // Change default wallet to test3 - // await goKey(tester, keyPay); - // await goKey(tester, keyChangeChest); - // await goKey(tester, keySelectThisWallet(test2.address)); - // await goKey(tester, keyConfirm); - // await sleep(tester); - - // // Certify with test3 account - // await goKey(tester, keyCertify); - // await goKey(tester, keyConfirm); - // await spawnBlock(tester, duration: 500); - // await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - // await goKey(tester, keyCloseTransactionScreen); - // await waitFor(tester, 'Vous devez attendre'); - - await waitFor(tester, '2', exactMatch: true); - await certify(tester, - fromAddress: test3.address, destAddress: test5.address); - await waitFor(tester, '3', exactMatch: true); - await certify(tester, - fromAddress: test4.address, destAddress: test5.address); - await waitFor(tester, '4', exactMatch: true); - await pay(tester, + await waitFor('25.0 $currencyName'); + await spawnBlock(); + await waitFor('22.0 $currencyName'); + await bkCertify(fromAddress: test1.address, destAddress: test5.address); + await waitFor('1', exactMatch: true); + await bkConfirmIdentity(fromAddress: test5.address, name: test5.name); + await bkCertify(fromAddress: test2.address, destAddress: test5.address); + await waitFor('2', exactMatch: true); + await bkCertify(fromAddress: test3.address, destAddress: test5.address); + await waitFor('3', exactMatch: true); + await bkCertify(fromAddress: test4.address, destAddress: test5.address); + await waitFor('4', exactMatch: true); + await bkPay( fromAddress: test2.address, destAddress: test5.address, amount: 40); - await waitFor(tester, '61.99 $currencyName'); - await spawnBlock(tester, until: 25); - }); + await waitFor('61.99 $currencyName'); + await spawnBlock(until: 10); + await waitFor('161.99 $currencyName'); + await spawnBlock(until: 20); + await waitFor('261.99 $currencyName'); + }, timeout: testTimeout()); } diff --git a/integration_test/duniter/data/gecko_tests.json b/integration_test/duniter/data/gecko_tests.json index 1cbcf63..ccd5486 100644 --- a/integration_test/duniter/data/gecko_tests.json +++ b/integration_test/duniter/data/gecko_tests.json @@ -1,8 +1,8 @@ { "first_ud": 10000, - "first_ud_reeval": 100, + "first_ud_reeval": 50, "genesis_parameters": { - "genesis_certs_expire_on": 50, + "genesis_certs_expire_on": 500, "genesis_certs_min_received": 3, "genesis_memberships_expire_on": 1051200, "genesis_smith_certs_expire_on": 2102400, diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index 320577a..e49447e 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -1,4 +1,5 @@ import 'package:flutter/services.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; @@ -6,118 +7,135 @@ import 'package:gecko/main.dart' as app; import 'general_actions.dart'; import 'tests_utility.dart'; -void main() { +void main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(); - testWidgets('Gecko complete', (tester) async { + testWidgets('Gecko complete', (testerLoc) async { + tester = testerLoc; app.main(); - await tester.pumpAndSettle(const Duration(seconds: 1)); + await waitFor('Test starting...', reverse: true); + await tester.pumpAndSettle(const Duration(milliseconds: 100)); + await sleep(2000); // Change Duniter endpoint to local - await changeNode(tester); + await changeNode(); // Delete all existing chests is exists - await deleteAllWallets(tester); + await deleteAllWallets(); // Restore the test chest - await restoreChest(tester); + await restoreChest(); // Execute a transaction to test2 - await payTest2(tester); + await payTest2(); // Certify test5 account with 3 accounts to become member - await certifyTest5(tester); - }); + await certifyTest5(); + }, timeout: testTimeout()); } -Future payTest2(WidgetTester tester) async { - await waitFor(tester, 'Rechercher'); - await goKey(tester, keyOpenSearch); +Future payTest2() async { + await waitFor('Rechercher'); + await goKey(keyOpenSearch); final addressToSearch = (await Clipboard.getData('text/plain'))!.text; final endAddress = addressToSearch!.substring(addressToSearch.length - 6); expect(addressToSearch, test5.address); - await enterText(tester, keySearchField, addressToSearch); - await goKey(tester, keyConfirmSearch); - await waitFor(tester, endAddress); - await goKey(tester, keySearchResult(addressToSearch)); - await waitFor(tester, endAddress); - await waitFor(tester, '0.0 ĞD'); - await goKey(tester, keyPay); - await enterText(tester, keyAmountField, '12.14'); - await goKey(tester, keyConfirmPayment); - await spawnBlock(tester); + await enterText(keySearchField, addressToSearch); + await goKey(keyConfirmSearch); + await waitFor(endAddress); + await goKey(keySearchResult(addressToSearch)); + await waitFor(endAddress); + await waitFor('0.0 ĞD'); + await goKey(keyPay); + await enterText(keyAmountField, '12.14'); + await goKey(keyConfirmPayment); + spawnBlock(duration: 500); - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen, duration: 0); - await waitFor(tester, '12.14'); - await spawnBlock(tester); - await waitFor(tester, '9.14'); + await waitFor('validé !', timeout: const Duration(seconds: 1)); + await goKey(keyCloseTransactionScreen, duration: 0); + await waitFor('12.14'); + spawnBlock(duration: 500); + await waitFor('9.14'); + humanRead(2); } -Future certifyTest5(WidgetTester tester) async { +Future certifyTest5() async { // Create identity with Test1 account - await goKey(tester, keyCertify); - await goKey(tester, keyConfirm); - await spawnBlock(tester, duration: 500); - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen); - await waitFor(tester, 'Identité créée'); + await goKey(keyCertify); + await goKey(keyConfirm); + spawnBlock(duration: 500); + await waitFor('validé !', timeout: const Duration(seconds: 1)); + await goKey(keyCloseTransactionScreen); + await waitFor('Identité créée'); // Confirm Identity Test5 - await goKey(tester, keyAppBarChest, duration: 300); - await goKey(tester, keyOpenWallet(test5.address)); - await goKey(tester, keyCopyAddress); - await goKey(tester, keyConfirmIdentity); - await enterText(tester, keyEnterIdentityUsername, test5.name); - await goKey(tester, keyConfirm); - await spawnBlock(tester, duration: 500); - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen); - await waitFor(tester, 'Identité confirmée'); - + await goKey(keyAppBarChest, duration: 300); + await goKey(keyOpenWallet(test5.address)); + await goKey(keyCopyAddress); + humanRead(3); + await goKey(keyConfirmIdentity); + await enterText(keyEnterIdentityUsername, test5.name); + await goKey(keyConfirm); + spawnBlock(duration: 500); + await waitFor('validé !', timeout: const Duration(seconds: 1)); + await goKey(keyCloseTransactionScreen); + await waitFor('Identité confirmée'); + humanRead(2); // Set wallet 2 as default wallet - await goBack(tester); - await goKey(tester, keyOpenWallet(test2.address)); - await goKey(tester, keySetDefaultWallet); - await waitFor(tester, 'Ce portefeuille est celui par defaut'); + await goBack(); + await goKey(keyOpenWallet(test2.address)); + await goKey(keySetDefaultWallet); + await waitFor('Ce portefeuille est celui par defaut'); // Search Wallet 5 again - await goKey(tester, keyAppBarSearch); + await goKey(keyAppBarSearch); final addressToSearch = (await Clipboard.getData('text/plain'))!.text; final endAddress = addressToSearch!.substring(addressToSearch.length - 6); expect(addressToSearch, test5.address); - await enterText(tester, keySearchField, addressToSearch); - await goKey(tester, keyConfirmSearch); - await waitFor(tester, endAddress); - await goKey(tester, keySearchResult(addressToSearch)); - await waitFor(tester, endAddress); - await waitFor(tester, '1'); + await enterText(keySearchField, addressToSearch); + await goKey(keyConfirmSearch); + await waitFor(endAddress); + await goKey(keySearchResult(addressToSearch)); + await waitFor(endAddress); + await waitFor('1'); // Certify with test2 account - await goKey(tester, keyCertify); - await goKey(tester, keyConfirm); - await spawnBlock(tester, duration: 500); - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen); - await waitFor(tester, '2'); + await goKey(keyCertify); + await goKey(keyConfirm); + spawnBlock(duration: 500); + await waitFor('validé !', timeout: const Duration(seconds: 1)); + await goKey(keyCloseTransactionScreen); + await waitFor('2'); // Change default wallet to test3 - await goKey(tester, keyPay); - await goKey(tester, keyChangeChest); - await goKey(tester, keySelectThisWallet(test3.address)); - await goKey(tester, keyConfirm); - await sleep(tester); + await goKey(keyPay); + await goKey(keyChangeChest); + await goKey(keySelectThisWallet(test3.address)); + await goKey(keyConfirm); + await sleep(); // Certify with test3 account - await goKey(tester, keyCertify); - await goKey(tester, keyConfirm); - await spawnBlock(tester, duration: 500); - await waitFor(tester, 'validé !', timeout: const Duration(seconds: 1)); - await goKey(tester, keyCloseTransactionScreen); - await waitFor(tester, 'Vous devez attendre'); + await goKey(keyCertify); + await goKey(keyConfirm); + spawnBlock(duration: 500); + await waitFor('validé !', timeout: const Duration(seconds: 1)); + await goKey(keyCloseTransactionScreen); + await waitFor('Vous devez attendre'); // Check if test5 is member - await goKey(tester, keyAppBarChest, duration: 300); - await goKey(tester, keyOpenWallet(test5.address)); - await waitFor(tester, 'Membre validé !'); + await goKey(keyAppBarChest, duration: 300); + await goKey(keyOpenWallet(test5.address)); + await waitFor('Membre validé !'); + + // spawn 20 blocs and check if ud is creating + await spawnBlock(until: 10); + await waitFor('109.13'); + await spawnBlock(until: 20); + await waitFor('209.13'); + + // Check UD reval + await spawnBlock(until: 50); + await waitFor('509.35'); + humanRead(5); } diff --git a/integration_test/general_actions.dart b/integration_test/general_actions.dart index 4ad5057..ee4fb35 100644 --- a/integration_test/general_actions.dart +++ b/integration_test/general_actions.dart @@ -8,89 +8,92 @@ import 'tests_utility.dart'; // GENERAL ACTIONS -Future changeNode(WidgetTester tester) async { +Future changeNode() async { final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; log.d('ip address: $ipAddress'); - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keySelectDuniterNodeDropDown, duration: 5); - await goKey(tester, keySelectDuniterNode('Personnalisé'), selectLast: true); - await enterText(tester, keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); - await goKey(tester, keyConnectToEndpoint); - await isIconPresent(tester, Icons.add_card_sharp, + await goKey(keyDrawerMenu); + await goKey(keyParameters); + await goKey(keySelectDuniterNodeDropDown, duration: 5); + await goKey(keySelectDuniterNode('Personnalisé'), selectLast: true); + await enterText(keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); + await goKey(keyConnectToEndpoint); + await isIconPresent(Icons.add_card_sharp, timeout: const Duration(seconds: 8)); - await goBack(tester); + await goBack(); } -Future deleteAllWallets(WidgetTester tester) async { - if (await isPresent(tester, 'Rechercher')) { - await goKey(tester, keyDrawerMenu); - await goKey(tester, keyParameters); - await goKey(tester, keyDeleteAllWallets); - await goKey(tester, keyConfirm); +Future deleteAllWallets() async { + if (await isPresent('Rechercher')) { + await goKey(keyDrawerMenu); + await goKey(keyParameters); + await goKey(keyDeleteAllWallets); + await goKey(keyConfirm); await tester.pumpAndSettle(); } } -Future restoreChest(WidgetTester tester) async { +Future restoreChest() async { // Copy test mnemonic in clipboard Clipboard.setData(const ClipboardData(text: testMnemonic)); // Open screen import chest - await goKey(tester, keyRestoreChest); - - // Wait frame stop before continue - await tester.pumpAndSettle(); + await goKey(keyRestoreChest, duration: 0); // Tap on button to paste mnemonic - await goKey(tester, keyPastMnemonic); + await goKey(keyPastMnemonic); // Tap on next button 4 times to skip 3 screen - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); - await goKey(tester, keyGoNext); + await goKey(keyGoNext); + await goKey(keyGoNext); + await goKey(keyGoNext); + await goKey(keyGoNext); // Check if cached password checkbox is checked - final isCached = await isIconPresent(tester, Icons.check_box); + final isCached = await isIconPresent(Icons.check_box); // If not, tap on to cache password - if (!isCached) await goKey(tester, keyCachePassword, duration: 0); + if (!isCached) await goKey(keyCachePassword, duration: 0); // Enter password - await enterText(tester, keyPinForm, 'AAAAA', 0); + await enterText(keyPinForm, 'AAAAA', 0); // Check if string "Accéder à mon coffre" is present in screen - await waitFor(tester, 'Accéder à mon coffre'); + await waitFor('Accéder à mon coffre'); // Go to wallets home - await goKey(tester, keyGoWalletsHome, duration: 0); + await goKey(keyGoWalletsHome, duration: 0); // Check if string "ĞD" is present in screen - await waitFor(tester, 'ĞD'); + await waitFor('ĞD'); // Tap on add a new derivation button - await addDerivation(tester); + await addDerivation(); // Tap on Wallet 5 - await goKey(tester, keyOpenWallet(test5.address)); + await goKey(keyOpenWallet(test5.address)); // Copy address of Wallet 5 - await goKey(tester, keyCopyAddress); + await goKey(keyCopyAddress); // Check if string "Cette adresse a été copié" is present in screen - await waitFor(tester, 'Cette adresse a été copié'); + await waitFor('Cette adresse a été copié'); - // Pop screen 2 time to go back home screen - await goBack(tester); - await goBack(tester); - - // Check if string "y'a pas de lézard" is present in screen - await waitFor(tester, "y'a pas de lézard"); + // Pop screen 2 time to go back home + await goBack(); + await goBack(); } -Future addDerivation(WidgetTester tester) async { - await goKey(tester, keyAddDerivation); - await waitFor(tester, 'Portefeuille 5'); +Future addDerivation() async { + await goKey(keyAddDerivation); + await waitFor('Portefeuille 5'); +} + +Future firstOpenChest() async { + await goKey(keyOpenWalletsHomme); + sleep(300); + final isCached = await isIconPresent(Icons.check_box); + if (!isCached) await goKey(keyCachePassword, duration: 0); + await enterText(keyPinForm, 'AAAAA', 0); + await waitFor('100.0 $currencyName'); } diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh index c4a4b87..9259b2f 100755 --- a/integration_test/launch_test.sh +++ b/integration_test/launch_test.sh @@ -1,15 +1,13 @@ #!/bin/bash -# MP="`dirname \"$0\"`" -# MP="`( cd \"$MP\" && pwd )`" -# cd $MP - testName=$1 +option=$2 [[ ! $testName ]] && testName='gecko_complete' # Get local IP and set .env ip_address=$(hostname -I | awk '{print $1}') echo "ip_address=$ip_address" > .env +[[ $option == 'human' ]] && echo "isHumanReading=true" >> .env ## Start local Duniter node cd integration_test/duniter diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 5c5a410..77b3189 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -1,10 +1,21 @@ import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; +import 'package:gecko/models/wallet_data.dart'; +import 'package:gecko/providers/generate_wallets.dart'; +import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:provider/provider.dart'; +import 'dart:io' as io; +import 'package:gecko/main.dart' as app; +final bool isHumanReading = + dotenv.env['isHumanReading'] == 'true' ? true : false; +Timeout testTimeout([int seconds = 120]) => + Timeout(Duration(seconds: isHumanReading ? 600 : seconds)); final sub = Provider.of(homeContext, listen: false); +late WidgetTester tester; // TEST WALLETS CONSTS const testMnemonic = @@ -28,11 +39,15 @@ final test5 = // CUSTOM FUNCTIONS -Future sleep(WidgetTester tester, [int time = 1000]) async { +Future sleep([int time = 1000]) async { await Future.delayed(Duration(milliseconds: time)); } -Future goKey(WidgetTester tester, Key buttonKey, +Future humanRead([int time = 1, bool force = false]) async { + if (isHumanReading || force) io.sleep(Duration(seconds: time)); +} + +Future goKey(Key buttonKey, {Finder? customFinder, int duration = 100, bool selectLast = false}) async { if (duration != 0) { await tester.pumpAndSettle(Duration(milliseconds: duration)); @@ -40,26 +55,27 @@ Future goKey(WidgetTester tester, Key buttonKey, final Finder finder = customFinder ?? find.byKey(buttonKey); log.d('INTEGRATION TEST: Tap on ${finder.description}}'); await tester.tap(selectLast ? finder.last : finder); - // await tester.pumpAndSettle(Duration(milliseconds: duration)); + humanRead(); } -Future goBack(WidgetTester tester) async { +Future goBack() async { final NavigatorState navigator = tester.state(find.byType(Navigator)); log.d('INTEGRATION TEST: Go back'); navigator.pop(); await tester.pump(); + humanRead(); } -Future enterText(WidgetTester tester, Key fieldKey, String textIn, - [int duration = 200]) async { +Future enterText(Key fieldKey, String textIn, [int duration = 200]) async { if (duration != 0) { await tester.pumpAndSettle(Duration(milliseconds: duration)); } log.d('INTEGRATION TEST: Enter text: $textIn'); await tester.enterText(find.byKey(fieldKey), textIn); + humanRead(); } -Future waitFor(WidgetTester tester, String text, +Future waitFor(String text, {Duration timeout = const Duration(seconds: 5), bool reverse = false, bool exactMatch = false}) async { @@ -76,41 +92,44 @@ Future waitFor(WidgetTester tester, String text, await tester.pumpAndSettle(); await Future.delayed(const Duration(milliseconds: 100)); } while (reverse ? finder.evaluate().isNotEmpty : finder.evaluate().isEmpty); + humanRead(); } // Test if text is visible on screen, return a boolean -Future isPresent(WidgetTester tester, String text, +Future isPresent(String text, {Duration timeout = const Duration(seconds: 1)}) async { try { - await waitFor(tester, text, timeout: timeout); + await waitFor(text, timeout: timeout); + humanRead(); return true; } catch (exception) { + humanRead(); return false; } } // Test if widget exist on screen, return a boolean -Future isIconPresent(WidgetTester tester, IconData icon, +Future isIconPresent(IconData icon, {Duration timeout = const Duration(seconds: 1)}) async { await tester.pumpAndSettle(); final finder = find.byIcon(icon); log.d('tatatatatatata: ${finder.evaluate()}'); + humanRead(); return finder.evaluate().isEmpty ? false : true; } -Future spawnBlock(WidgetTester tester, - {int number = 1, int duration = 200, int? until}) async { +Future spawnBlock({int number = 1, int duration = 200, int? until}) async { if (duration != 0) { - await sleep(tester, duration); + await sleep(duration); } if (until != null) { number = until - sub.blocNumber; } await sub.spawnBlock(number); - await sleep(tester, 200); + await sleep(200); } -Future pay(WidgetTester tester, +Future bkPay( {required String fromAddress, required String destAddress, required double amount}) async { @@ -119,22 +138,22 @@ Future pay(WidgetTester tester, destAddress: destAddress, amount: amount, password: 'AAAAA'); - await spawnBlock(tester); - await sleep(tester, 500); + await spawnBlock(); + await sleep(500); } -Future certify(WidgetTester tester, +Future bkCertify( {required String fromAddress, required String destAddress}) async { sub.certify(fromAddress, destAddress, 'AAAAA'); - await spawnBlock(tester); - await sleep(tester, 500); + await spawnBlock(); + await sleep(500); } -Future confirmIdentity(WidgetTester tester, +Future bkConfirmIdentity( {required String fromAddress, required String name}) async { sub.confirmIdentity(fromAddress, name, 'AAAAA'); - await spawnBlock(tester); - await sleep(tester, 500); + await spawnBlock(); + await sleep(500); } class TestWallet { @@ -146,3 +165,79 @@ class TestWallet { endAddress() => address.substring(address.length - 6); shortAddress() => getShortPubkey(address); } + +Future bkSetNode([String? endpoint]) async { + if (endpoint == null) { + final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; + endpoint = 'ws://$ipAddress:9944'; + } + configBox.put('customEndpoint', endpoint); + sub.connectNode(homeContext); +} + +Future bkRestoreChest([String mnemonic = testMnemonic]) async { + final myWalletProvider = + Provider.of(homeContext, listen: false); + final generateWalletProvider = + Provider.of(homeContext, listen: false); + + await generateWalletProvider.storeHDWChest(homeContext); + + for (int number = 0; number <= 4; number++) { + await _addImportAccount( + mnemonic: mnemonic, + chest: 0, + number: number, + name: 'test${number + 1}', + derivation: (number + 1) * 2); + } + myWalletProvider.rebuildWidget(); +} + +Future _addImportAccount( + {required String mnemonic, + required int chest, + required int number, + required String name, + required int derivation}) async { + final address = await sub.importAccount( + mnemonic: mnemonic, derivePath: '//$derivation', password: 'AAAAA'); + final myWallet = WalletData( + version: dataVersion, + chest: chest, + address: address, + number: number, + name: name, + derivation: derivation, + imageDefaultPath: '${number % 4}.png'); + await walletBox.add(myWallet); + + return myWallet; +} + +Future bkDeleteAllWallets() async { + final myWalletProvider = + Provider.of(homeContext, listen: false); + if (myWalletProvider.listWallets.isNotEmpty) { + await myWalletProvider.deleteAllWallet(homeContext); + myWalletProvider.rebuildWidget(); + } +} + +Future fastStart() async { + app.main(); + await waitFor('Test starting...', reverse: true); + await tester.pumpAndSettle(const Duration(milliseconds: 100)); + await sleep(2000); + + // Connect to local endpoint + await bkSetNode(); + await sleep(); + + // Delete all existing chests is exists + await bkDeleteAllWallets(); + + // Restore the test chest + await bkRestoreChest(); + await waitFor("y'a pas de lézard"); +} diff --git a/integration_test/ud_creation_state.dart b/integration_test/ud_creation_state.dart new file mode 100644 index 0000000..bbf9fe7 --- /dev/null +++ b/integration_test/ud_creation_state.dart @@ -0,0 +1,29 @@ +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:integration_test/integration_test.dart'; +import 'general_actions.dart'; +import 'tests_utility.dart'; + +void main() async { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(); + + testWidgets('Gecko complete', (testerLoc) async { + tester = testerLoc; + // Connect local node and import test chest in background + await fastStart(); + + // Open chest + await firstOpenChest(); + + // Go to test1 options and check if balance growup with UDs creations + await goKey(keyOpenWallet(test1.address)); + await waitFor('100.0 $currencyName'); + await spawnBlock(until: 10); + await waitFor('200.0 $currencyName'); + await spawnBlock(until: 20); + await waitFor('300.0 $currencyName'); + }, timeout: testTimeout()); +} diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index d0511df..781b417 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -2,6 +2,7 @@ import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/chest_data.dart'; @@ -940,7 +941,11 @@ newKeySig: $newKeySig"""); await sdk.api.keyring.deleteAccount(keyring, keypair); } - Future spawnBlock([int number = 1]) async { + Future spawnBlock([int number = 1, int until = 0]) async { + if (!kDebugMode) return; + if (blocNumber < until) { + number = until - blocNumber; + } for (var i = 1; i <= number; i++) { await sdk.webView! .evalJavascript('api.rpc.engine.createBlock(true, true)'); diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index de5e74e..5d6c5eb 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -38,6 +38,10 @@ class WalletOptions extends StatelessWidget { DuniterIndexer duniterIndexer = Provider.of(context, listen: false); + // SubstrateSdk sub = Provider.of(context, listen: false); + // sub.spawnBlock(); + // sub.spawnBlock(0, 25); + log.d(walletOptions.address.text); final int currentChest = myWalletProvider.getCurrentChest(); diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index d02757b..6089693 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -43,12 +43,15 @@ class WalletViewScreen extends StatelessWidget { SubstrateSdk sub = Provider.of(context, listen: false); HomeProvider homeProvider = Provider.of(context, listen: false); - MyWalletsProvider myWalletProvider = Provider.of(context, listen: false); WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); + sub.setCurrentWallet(defaultWallet); + // sub.spawnBlock(); + // sub.spawnBlock(0, 25); + return Scaffold( backgroundColor: backgroundColor, resizeToAvoidBottomInset: true, From 939c6b31081197af18be0a2d22ff06cf0e58037c Mon Sep 17 00:00:00 2001 From: poka Date: Sun, 28 Aug 2022 05:15:58 +0200 Subject: [PATCH 16/28] remove old integration test bash script --- scripts/startIntegrationsTests.sh | 3 --- 1 file changed, 3 deletions(-) delete mode 100755 scripts/startIntegrationsTests.sh diff --git a/scripts/startIntegrationsTests.sh b/scripts/startIntegrationsTests.sh deleted file mode 100755 index eca24d1..0000000 --- a/scripts/startIntegrationsTests.sh +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/bash - -flutter drive --target=test_driver/app.dart From 9301eaf1a76df381d62ebcce340c6bbd15ff4f5d Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 29 Aug 2022 06:03:05 +0200 Subject: [PATCH 17/28] add test: migrate Cesium wallet identity --- integration_test/cert_state.dart | 10 +- .../duniter/data/gecko_tests.json | 5 + integration_test/gecko_complete.dart | 84 +++++++------- integration_test/general_actions.dart | 47 ++++---- integration_test/migrate_cesium_identity.dart | 66 +++++++++++ integration_test/tests_utility.dart | 106 ++++++++++++++---- integration_test/ud_creation_state.dart | 6 +- lib/models/widgets_keys.dart | 6 + lib/providers/generate_wallets.dart | 1 + lib/providers/substrate_sdk.dart | 3 +- lib/screens/myWallets/import_g1_v1.dart | 31 +++-- 11 files changed, 251 insertions(+), 114 deletions(-) create mode 100644 integration_test/migrate_cesium_identity.dart diff --git a/integration_test/cert_state.dart b/integration_test/cert_state.dart index bbfe692..f36dc5c 100644 --- a/integration_test/cert_state.dart +++ b/integration_test/cert_state.dart @@ -10,21 +10,21 @@ void main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); await dotenv.load(); - testWidgets('Gecko complete', (testerLoc) async { + testWidgets('Certifications state', (testerLoc) async { tester = testerLoc; // Connect local node and import test chest in background - await fastStart(); + await bkFastStart(); // Open chest await firstOpenChest(); await goBack(); // Go wallet 5 view - await goKey(keyOpenSearch); + await tapKey(keyOpenSearch); await enterText(keySearchField, test5.address); - await goKey(keyConfirmSearch); + await tapKey(keyConfirmSearch); await waitFor(test5.shortAddress()); - await goKey(keySearchResult(test5.address)); + await tapKey(keySearchResult(test5.address)); await waitFor('Certifier'); await waitFor('Vous devez ', reverse: true); await waitFor('Vous pourrez renouveler ', reverse: true); diff --git a/integration_test/duniter/data/gecko_tests.json b/integration_test/duniter/data/gecko_tests.json index ccd5486..804b3de 100644 --- a/integration_test/duniter/data/gecko_tests.json +++ b/integration_test/duniter/data/gecko_tests.json @@ -29,6 +29,11 @@ "balance": 10000, "certs": ["test1", "test2", "test3"], "pubkey": "5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5" + }, + "testCesium1": { + "balance": 10000, + "certs": ["test1", "test2", "test3"], + "pubkey": "5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1" } }, "parameters": { diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index e49447e..7157f11 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -1,9 +1,7 @@ -import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; -import 'package:gecko/main.dart' as app; import 'general_actions.dart'; import 'tests_utility.dart'; @@ -12,11 +10,11 @@ void main() async { await dotenv.load(); testWidgets('Gecko complete', (testerLoc) async { + // Share WidgetTester to test provider tester = testerLoc; - app.main(); - await waitFor('Test starting...', reverse: true); - await tester.pumpAndSettle(const Duration(milliseconds: 100)); - await sleep(2000); + + // Start app and wait finish starting + await startWait(); // Change Duniter endpoint to local await changeNode(); @@ -27,7 +25,7 @@ void main() async { // Restore the test chest await restoreChest(); - // Execute a transaction to test2 + // Execute a transaction to test5 await payTest2(); // Certify test5 account with 3 accounts to become member @@ -37,23 +35,23 @@ void main() async { Future payTest2() async { await waitFor('Rechercher'); - await goKey(keyOpenSearch); - final addressToSearch = (await Clipboard.getData('text/plain'))!.text; - final endAddress = addressToSearch!.substring(addressToSearch.length - 6); + await tapKey(keyOpenSearch); + final addressToSearch = await clipPaste(); + final endAddress = addressToSearch.substring(addressToSearch.length - 6); expect(addressToSearch, test5.address); await enterText(keySearchField, addressToSearch); - await goKey(keyConfirmSearch); + await tapKey(keyConfirmSearch); await waitFor(endAddress); - await goKey(keySearchResult(addressToSearch)); + await tapKey(keySearchResult(addressToSearch)); await waitFor(endAddress); await waitFor('0.0 ĞD'); - await goKey(keyPay); + await tapKey(keyPay); await enterText(keyAmountField, '12.14'); - await goKey(keyConfirmPayment); + await tapKey(keyConfirmPayment); spawnBlock(duration: 500); await waitFor('validé !', timeout: const Duration(seconds: 1)); - await goKey(keyCloseTransactionScreen, duration: 0); + await tapKey(keyCloseTransactionScreen, duration: 0); await waitFor('12.14'); spawnBlock(duration: 500); await waitFor('9.14'); @@ -62,70 +60,70 @@ Future payTest2() async { Future certifyTest5() async { // Create identity with Test1 account - await goKey(keyCertify); - await goKey(keyConfirm); + await tapKey(keyCertify); + await tapKey(keyConfirm); spawnBlock(duration: 500); await waitFor('validé !', timeout: const Duration(seconds: 1)); - await goKey(keyCloseTransactionScreen); + await tapKey(keyCloseTransactionScreen); await waitFor('Identité créée'); // Confirm Identity Test5 - await goKey(keyAppBarChest, duration: 300); - await goKey(keyOpenWallet(test5.address)); - await goKey(keyCopyAddress); + await tapKey(keyAppBarChest, duration: 300); + await tapKey(keyOpenWallet(test5.address)); + await tapKey(keyCopyAddress); humanRead(3); - await goKey(keyConfirmIdentity); + await tapKey(keyConfirmIdentity); await enterText(keyEnterIdentityUsername, test5.name); - await goKey(keyConfirm); + await tapKey(keyConfirm); spawnBlock(duration: 500); await waitFor('validé !', timeout: const Duration(seconds: 1)); - await goKey(keyCloseTransactionScreen); + await tapKey(keyCloseTransactionScreen); await waitFor('Identité confirmée'); humanRead(2); // Set wallet 2 as default wallet await goBack(); - await goKey(keyOpenWallet(test2.address)); - await goKey(keySetDefaultWallet); + await tapKey(keyOpenWallet(test2.address)); + await tapKey(keySetDefaultWallet); await waitFor('Ce portefeuille est celui par defaut'); // Search Wallet 5 again - await goKey(keyAppBarSearch); - final addressToSearch = (await Clipboard.getData('text/plain'))!.text; - final endAddress = addressToSearch!.substring(addressToSearch.length - 6); + await tapKey(keyAppBarSearch); + final addressToSearch = await clipPaste(); + final endAddress = addressToSearch.substring(addressToSearch.length - 6); expect(addressToSearch, test5.address); await enterText(keySearchField, addressToSearch); - await goKey(keyConfirmSearch); + await tapKey(keyConfirmSearch); await waitFor(endAddress); - await goKey(keySearchResult(addressToSearch)); + await tapKey(keySearchResult(addressToSearch)); await waitFor(endAddress); await waitFor('1'); // Certify with test2 account - await goKey(keyCertify); - await goKey(keyConfirm); + await tapKey(keyCertify); + await tapKey(keyConfirm); spawnBlock(duration: 500); await waitFor('validé !', timeout: const Duration(seconds: 1)); - await goKey(keyCloseTransactionScreen); + await tapKey(keyCloseTransactionScreen); await waitFor('2'); // Change default wallet to test3 - await goKey(keyPay); - await goKey(keyChangeChest); - await goKey(keySelectThisWallet(test3.address)); - await goKey(keyConfirm); + await tapKey(keyPay); + await tapKey(keyChangeChest); + await tapKey(keySelectThisWallet(test3.address)); + await tapKey(keyConfirm); await sleep(); // Certify with test3 account - await goKey(keyCertify); - await goKey(keyConfirm); + await tapKey(keyCertify); + await tapKey(keyConfirm); spawnBlock(duration: 500); await waitFor('validé !', timeout: const Duration(seconds: 1)); - await goKey(keyCloseTransactionScreen); + await tapKey(keyCloseTransactionScreen); await waitFor('Vous devez attendre'); // Check if test5 is member - await goKey(keyAppBarChest, duration: 300); - await goKey(keyOpenWallet(test5.address)); + await tapKey(keyAppBarChest, duration: 300); + await tapKey(keyOpenWallet(test5.address)); await waitFor('Membre validé !'); // spawn 20 blocs and check if ud is creating diff --git a/integration_test/general_actions.dart b/integration_test/general_actions.dart index ee4fb35..cf8dfc1 100644 --- a/integration_test/general_actions.dart +++ b/integration_test/general_actions.dart @@ -1,5 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; @@ -12,12 +11,12 @@ Future changeNode() async { final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; log.d('ip address: $ipAddress'); - await goKey(keyDrawerMenu); - await goKey(keyParameters); - await goKey(keySelectDuniterNodeDropDown, duration: 5); - await goKey(keySelectDuniterNode('Personnalisé'), selectLast: true); + await tapKey(keyDrawerMenu); + await tapKey(keyParameters); + await tapKey(keySelectDuniterNodeDropDown, duration: 5); + await tapKey(keySelectDuniterNode('Personnalisé'), selectLast: true); await enterText(keyCustomDuniterEndpoint, 'ws://$ipAddress:9944'); - await goKey(keyConnectToEndpoint); + await tapKey(keyConnectToEndpoint); await isIconPresent(Icons.add_card_sharp, timeout: const Duration(seconds: 8)); await goBack(); @@ -25,35 +24,35 @@ Future changeNode() async { Future deleteAllWallets() async { if (await isPresent('Rechercher')) { - await goKey(keyDrawerMenu); - await goKey(keyParameters); - await goKey(keyDeleteAllWallets); - await goKey(keyConfirm); + await tapKey(keyDrawerMenu); + await tapKey(keyParameters); + await tapKey(keyDeleteAllWallets); + await tapKey(keyConfirm); await tester.pumpAndSettle(); } } Future restoreChest() async { // Copy test mnemonic in clipboard - Clipboard.setData(const ClipboardData(text: testMnemonic)); + await clipCopy(testMnemonic); // Open screen import chest - await goKey(keyRestoreChest, duration: 0); + await tapKey(keyRestoreChest, duration: 0); // Tap on button to paste mnemonic - await goKey(keyPastMnemonic); + await tapKey(keyPastMnemonic); // Tap on next button 4 times to skip 3 screen - await goKey(keyGoNext); - await goKey(keyGoNext); - await goKey(keyGoNext); - await goKey(keyGoNext); + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await tapKey(keyGoNext); // Check if cached password checkbox is checked final isCached = await isIconPresent(Icons.check_box); // If not, tap on to cache password - if (!isCached) await goKey(keyCachePassword, duration: 0); + if (!isCached) await tapKey(keyCachePassword, duration: 0); // Enter password await enterText(keyPinForm, 'AAAAA', 0); @@ -62,7 +61,7 @@ Future restoreChest() async { await waitFor('Accéder à mon coffre'); // Go to wallets home - await goKey(keyGoWalletsHome, duration: 0); + await tapKey(keyGoWalletsHome, duration: 0); // Check if string "ĞD" is present in screen await waitFor('ĞD'); @@ -71,10 +70,10 @@ Future restoreChest() async { await addDerivation(); // Tap on Wallet 5 - await goKey(keyOpenWallet(test5.address)); + await tapKey(keyOpenWallet(test5.address)); // Copy address of Wallet 5 - await goKey(keyCopyAddress); + await tapKey(keyCopyAddress); // Check if string "Cette adresse a été copié" is present in screen await waitFor('Cette adresse a été copié'); @@ -85,15 +84,15 @@ Future restoreChest() async { } Future addDerivation() async { - await goKey(keyAddDerivation); + await tapKey(keyAddDerivation); await waitFor('Portefeuille 5'); } Future firstOpenChest() async { - await goKey(keyOpenWalletsHomme); + await tapKey(keyOpenWalletsHomme); sleep(300); final isCached = await isIconPresent(Icons.check_box); - if (!isCached) await goKey(keyCachePassword, duration: 0); + if (!isCached) await tapKey(keyCachePassword, duration: 0); await enterText(keyPinForm, 'AAAAA', 0); await waitFor('100.0 $currencyName'); } diff --git a/integration_test/migrate_cesium_identity.dart b/integration_test/migrate_cesium_identity.dart new file mode 100644 index 0000000..79cb510 --- /dev/null +++ b/integration_test/migrate_cesium_identity.dart @@ -0,0 +1,66 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/globals.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:integration_test/integration_test.dart'; +import 'general_actions.dart'; +import 'tests_utility.dart'; + +void main() async { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(); + + testWidgets('Migrate Cesium identity and balance', (testerLoc) async { + tester = testerLoc; + // Connect local node and import test chest in background + await bkFastStart(); + + // Open chest + await firstOpenChest(); + + // Go to test1 options and check if balance growup with UDs creations + await tapKey(keyAddDerivation); + await waitFor('Portefeuille 6'); + + await scrollUntil(keyImportG1v1); + await tapKey(keyImportG1v1); + await enterText(keyCesiumId, 'test'); + await enterText(keyCesiumPassword, 'test'); + await waitFor(cesiumTest1.shortAddress()); + await waitFor('100.0 $currencyName'); + await waitFor('3', exactMatch: true); + + isObscureText(); + await tapKey(keyCesiumIdVisible); + await tester.pumpAndSettle(); + isObscureText(false); + await tapKey(keyCesiumIdVisible); + await tester.pumpAndSettle(); + isObscureText(); + + await tapKey(keySelectWallet); + await tapKey(keySelectThisWallet(test6.address), selectLast: true); + await waitForButtonEnabled(keyConfirm); + await tapKey(keyConfirm); + spawnBlock(duration: 2000); + await waitFor('validé !'); + await tapKey(keyCloseTransactionScreen, duration: 0); + + await tapKey(keyOpenWallet(test6.address), duration: 300); + await waitFor('3', exactMatch: true); + await waitFor('Membre validé !'); + + // TODO: fix batch for transfertAll + // await waitFor('100.0 $currencyName'); + }, timeout: testTimeout()); +} + +isObscureText([bool isObscure = true]) { + final passwordTextFormField = find.descendant( + of: find.byKey(keyCesiumId), + matching: find.byType(EditableText), + ); + final input = tester.widget(passwordTextFormField); + expect(input.obscureText, isObscure ? isTrue : isFalse); +} diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index 77b3189..bb39cab 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; @@ -30,12 +31,20 @@ final test4 = TestWallet('5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5', 'test4'); final test5 = TestWallet('5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R', 'test5'); -// final test6 = -// TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test6'); -// final test7 = -// TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test7'); -// final test8 = -// TestWallet('5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa', 'test8'); +final test6 = + TestWallet('5GxEp3do81j97kNaH4JyZgDXuPoKWoTuxXXWGyyNXeKeVLHb', 'test6'); +final test7 = + TestWallet('5FZ1sSvREbQLCtSSCvMUx7KCAnpJkB7q5mfz2oixiZq2ChET', 'test7'); +final test8 = + TestWallet('5CoKV9EEgwb2NmWamTXUAa6ycfNb2k1iNfVGvJAkg7dLq9RH', 'test8'); +final cesiumTest1 = TestWallet( + '5GAT6CJW8yVKwUuQc7sM5Kk9GZVTpbZYk9PfjNXtvnNgAJZ1', 'cesiumTest1'); +final cesiumTest2 = TestWallet( + '5DTnny1tTkUs1SXHZTx98RUAj76Z88FfFhsQjd48dXnk8gHR', 'cesiumTest2'); +final cesiumTest3 = TestWallet( + '5EJct9jTDNKco4YiYfETAseq1gaduBtsJUcNnFicfvh3bTV6', 'cesiumTest3'); +final cesiumTest4 = TestWallet( + '5HD1oSv6A7VNxPYos6F86JFZ3bhz5LnEaWC4hkwLMj84v4ww', 'cesiumTest4'); // CUSTOM FUNCTIONS @@ -43,11 +52,17 @@ Future sleep([int time = 1000]) async { await Future.delayed(Duration(milliseconds: time)); } +Future clipPaste() async => + (await Clipboard.getData('text/plain'))?.text ?? ''; + +clipCopy(String text) async => + await Clipboard.setData(ClipboardData(text: text)); + Future humanRead([int time = 1, bool force = false]) async { if (isHumanReading || force) io.sleep(Duration(seconds: time)); } -Future goKey(Key buttonKey, +Future tapKey(Key buttonKey, {Finder? customFinder, int duration = 100, bool selectLast = false}) async { if (duration != 0) { await tester.pumpAndSettle(Duration(milliseconds: duration)); @@ -58,6 +73,42 @@ Future goKey(Key buttonKey, humanRead(); } +Finder findByKey(Key key) { + return find.byKey(key); +} + +bool isButtonEnabled(Key key) { + return tester.widget(findByKey(key)).enabled; +} + +Future scrollUntil(Key element) async { + final findList = find.byType(Scrollable); + final findElement = findByKey(element); + await tester.scrollUntilVisible( + findElement, + 500.0, + scrollable: findList, + ); +} + +Future waitForButtonEnabled(Key key, + {Duration timeout = const Duration(seconds: 5), + bool reverse = false}) async { + final end = DateTime.now().add(timeout); + + log.d('INTEGRATION TEST: Wait for $key to be enabled'); + + do { + if (DateTime.now().isAfter(end)) { + throw Exception('Timed out waiting for button enabled: $key'); + } + + await tester.pumpAndSettle(); + await Future.delayed(const Duration(milliseconds: 100)); + } while (reverse ? isButtonEnabled(key) : !isButtonEnabled(key)); + humanRead(); +} + Future goBack() async { final NavigatorState navigator = tester.state(find.byType(Navigator)); log.d('INTEGRATION TEST: Go back'); @@ -129,6 +180,7 @@ Future spawnBlock({int number = 1, int duration = 200, int? until}) async { await sleep(200); } +// Pay in background Future bkPay( {required String fromAddress, required String destAddress, @@ -142,6 +194,7 @@ Future bkPay( await sleep(500); } +// Certify in background Future bkCertify( {required String fromAddress, required String destAddress}) async { sub.certify(fromAddress, destAddress, 'AAAAA'); @@ -149,6 +202,7 @@ Future bkCertify( await sleep(500); } +// Confirm my identity in background Future bkConfirmIdentity( {required String fromAddress, required String name}) async { sub.confirmIdentity(fromAddress, name, 'AAAAA'); @@ -156,16 +210,7 @@ Future bkConfirmIdentity( await sleep(500); } -class TestWallet { - String address; - String name; - - TestWallet(this.address, this.name); - - endAddress() => address.substring(address.length - 6); - shortAddress() => getShortPubkey(address); -} - +// Change node in background Future bkSetNode([String? endpoint]) async { if (endpoint == null) { final ipAddress = dotenv.env['ip_address'] ?? '127.0.0.1'; @@ -175,6 +220,7 @@ Future bkSetNode([String? endpoint]) async { sub.connectNode(homeContext); } +// Restore chest in background Future bkRestoreChest([String mnemonic = testMnemonic]) async { final myWalletProvider = Provider.of(homeContext, listen: false); @@ -215,6 +261,7 @@ Future _addImportAccount( return myWallet; } +// Delete all wallets in background Future bkDeleteAllWallets() async { final myWalletProvider = Provider.of(homeContext, listen: false); @@ -224,11 +271,9 @@ Future bkDeleteAllWallets() async { } } -Future fastStart() async { - app.main(); - await waitFor('Test starting...', reverse: true); - await tester.pumpAndSettle(const Duration(milliseconds: 100)); - await sleep(2000); +Future bkFastStart() async { + // Start app and wait finish starting + await startWait(); // Connect to local endpoint await bkSetNode(); @@ -241,3 +286,20 @@ Future fastStart() async { await bkRestoreChest(); await waitFor("y'a pas de lézard"); } + +Future startWait() async { + app.main(); + await waitFor('Test starting...', reverse: true); + await tester.pumpAndSettle(const Duration(milliseconds: 300)); + await sleep(2000); +} + +class TestWallet { + String address; + String name; + + TestWallet(this.address, this.name); + + endAddress() => address.substring(address.length - 6); + shortAddress() => getShortPubkey(address); +} diff --git a/integration_test/ud_creation_state.dart b/integration_test/ud_creation_state.dart index bbf9fe7..88e9abd 100644 --- a/integration_test/ud_creation_state.dart +++ b/integration_test/ud_creation_state.dart @@ -10,16 +10,16 @@ void main() async { IntegrationTestWidgetsFlutterBinding.ensureInitialized(); await dotenv.load(); - testWidgets('Gecko complete', (testerLoc) async { + testWidgets('UDs creation state', (testerLoc) async { tester = testerLoc; // Connect local node and import test chest in background - await fastStart(); + await bkFastStart(); // Open chest await firstOpenChest(); // Go to test1 options and check if balance growup with UDs creations - await goKey(keyOpenWallet(test1.address)); + await tapKey(keyOpenWallet(test1.address)); await waitFor('100.0 $currencyName'); await spawnBlock(until: 10); await waitFor('200.0 $currencyName'); diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index 58b3935..e10c39d 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -83,6 +83,12 @@ const keyGoWalletsHome = Key('keyGoWalletsHome'); const keySearchField = Key('keySearchField'); const keyConfirmSearch = Key('keyConfirmSearch'); +// Import Cesium wallet +const keyCesiumId = Key('keyCesiumId'); +const keyCesiumPassword = Key('keyCesiumPassword'); +const keySelectWallet = Key('keySelectWallet'); +const keyCesiumIdVisible = Key('keyCesiumIdVisible'); + // Items keys Key keyTransaction(int keyId) => Key('keyTransaction$keyId'); Key keyMnemonicWord(String word) => Key('keyMnemonicWord$word'); diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index 24aef78..43355a7 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -354,6 +354,7 @@ class GenerateWalletsProvider with ChangeNotifier { cellController10, cellController11 ]; + if (sentence?.text == null) return; for (var word in sentence!.text!.split(' ')) { bool isValid = isBipWord(word, false); diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index 781b417..d08a74a 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -38,7 +38,8 @@ class SubstrateSdk with ChangeNotifier { TextEditingController csSalt = TextEditingController(); TextEditingController csPassword = TextEditingController(); String g1V1NewAddress = ''; - bool isCesiumIDVisible = true; + bool isCesiumIDVisible = false; + bool isCesiumAddresLoading = false; ///////////////////////////////////// ////////// 1: API METHODS /////////// diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index 5b8b332..2683757 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -22,7 +22,6 @@ class ImportG1v1 extends StatelessWidget { @override Widget build(BuildContext context) { SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); - // HomeProvider _homeProvider = Provider.of(context); WalletOptionsProvider walletOptions = Provider.of(context, listen: false); MyWalletsProvider myWalletProvider = @@ -110,6 +109,7 @@ class ImportG1v1 extends StatelessWidget { return Column(children: [ const SizedBox(height: 20), TextFormField( + key: keyCesiumId, autofocus: true, onChanged: (text) { if (debounce?.isActive ?? false) { @@ -117,21 +117,23 @@ class ImportG1v1 extends StatelessWidget { } debounce = Timer( const Duration(milliseconds: debouneTime), () { + sub.reload(); sub.csToV2Address( sub.csSalt.text, sub.csPassword.text); }); }, keyboardType: TextInputType.text, controller: sub.csSalt, - obscureText: sub + obscureText: !sub .isCesiumIDVisible, //This will obscure text dynamically decoration: InputDecoration( hintText: 'enterCesiumId'.tr(), suffixIcon: IconButton( + key: keyCesiumIdVisible, icon: Icon( sub.isCesiumIDVisible - ? Icons.visibility - : Icons.visibility_off, + ? Icons.visibility_off + : Icons.visibility, color: Colors.black, ), onPressed: () { @@ -142,6 +144,7 @@ class ImportG1v1 extends StatelessWidget { ), const SizedBox(height: 20), TextFormField( + key: keyCesiumPassword, autofocus: true, onChanged: (text) { if (debounce?.isActive ?? false) { @@ -149,21 +152,23 @@ class ImportG1v1 extends StatelessWidget { } debounce = Timer( const Duration(milliseconds: debouneTime), () { + sub.g1V1NewAddress = ''; + sub.reload(); sub.csToV2Address( sub.csSalt.text, sub.csPassword.text); }); }, keyboardType: TextInputType.text, controller: sub.csPassword, - obscureText: sub + obscureText: !sub .isCesiumIDVisible, //This will obscure text dynamically decoration: InputDecoration( hintText: 'enterCesiumPassword'.tr(), suffixIcon: IconButton( icon: Icon( sub.isCesiumIDVisible - ? Icons.visibility - : Icons.visibility_off, + ? Icons.visibility_off + : Icons.visibility, color: Colors.black, ), onPressed: () { @@ -188,14 +193,6 @@ class ImportG1v1 extends StatelessWidget { ), ), ), - // Text( - // getShortPubkey(sub.g1V1NewAddress), - // style: const TextStyle( - // fontSize: 18, - // color: Colors.black, - // fontWeight: FontWeight.bold, - // fontFamily: 'Monospace'), - // ), const SizedBox(height: 20), Text( '${balance['transferableBalance']} $currencyName', @@ -214,12 +211,14 @@ class ImportG1v1 extends StatelessWidget { Text('selectDestWallet'.tr()), const SizedBox(height: 5), DropdownButtonHideUnderline( + key: keySelectWallet, child: DropdownButton( // alignment: AlignmentDirectional.topStart, value: selectedWallet, icon: const Icon(Icons.keyboard_arrow_down), items: myWalletProvider.listWallets.map((wallet) { return DropdownMenuItem( + key: keySelectThisWallet(wallet.address!), value: wallet, child: Text( wallet.name!, @@ -238,6 +237,7 @@ class ImportG1v1 extends StatelessWidget { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( + key: keyConfirm, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background @@ -245,7 +245,6 @@ class ImportG1v1 extends StatelessWidget { ), onPressed: canValidate ? () async { - log.d('GOOO'); WalletData? defaultWallet = myWalletProvider.getDefaultWallet(); From 37dee7f8663e746d781fb7843d4d754a4ebf1d46 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 29 Aug 2022 20:50:43 +0200 Subject: [PATCH 18/28] fix: transferAll in batch for identity migration --- lib/providers/substrate_sdk.dart | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index d08a74a..af1bbca 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -688,7 +688,7 @@ class SubstrateSdk with ChangeNotifier { ); const tx1 = 'api.tx.universalDividend.claimUds()'; final tx2 = amount == -1 - ? 'api.tx.balances.transferAll(false)' + ? 'api.tx.balances.transferAll("$destAddress", false)' : 'api.tx.balances.transferKeepAlive("$destAddress", $amountUnit)'; rawParams = '[[$tx1, $tx2]]'; @@ -851,10 +851,11 @@ newKeySig: $newKeySig"""); const tx1 = 'api.tx.universalDividend.claimUds()'; final tx2 = 'api.tx.identity.changeOwnerKey("$destAddress", "$newKeySig")'; - // const tx3 = 'api.tx.balances.transferAll(false)'; + final tx3 = 'api.tx.balances.transferAll("$destAddress", false)'; - rawParams = - fromBalance['unclaimedUds'] == 0 ? '[[$tx2]]' : '[[$tx1, $tx2]]'; + rawParams = fromBalance['unclaimedUds'] == 0 + ? '[[$tx2, $tx3]]' + : '[[$tx1, $tx2, $tx3]]'; } else { txInfo = TxInfoData( 'identity', From a8dbf79eaad1cf1238fb4b547291eb4c8a3ca716 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 29 Aug 2022 20:51:45 +0200 Subject: [PATCH 19/28] improve test migrate Cesium wallet identity: check if balance is well transfered --- integration_test/migrate_cesium_identity.dart | 3 +-- lib/screens/myWallets/wallet_options.dart | 2 +- lib/screens/myWallets/wallets_home.dart | 1 + lib/screens/transaction_in_progress.dart | 4 ++++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/integration_test/migrate_cesium_identity.dart b/integration_test/migrate_cesium_identity.dart index 79cb510..e57720f 100644 --- a/integration_test/migrate_cesium_identity.dart +++ b/integration_test/migrate_cesium_identity.dart @@ -51,8 +51,7 @@ void main() async { await waitFor('3', exactMatch: true); await waitFor('Membre validé !'); - // TODO: fix batch for transfertAll - // await waitFor('100.0 $currencyName'); + await waitFor('99.98 $currencyName'); }, timeout: testTimeout()); } diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index 5d6c5eb..f213449 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -40,7 +40,7 @@ class WalletOptions extends StatelessWidget { // SubstrateSdk sub = Provider.of(context, listen: false); // sub.spawnBlock(); - // sub.spawnBlock(0, 25); + // sub.spawnBlock(0, 20); log.d(walletOptions.address.text); diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index cdf307e..7e452bf 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -36,6 +36,7 @@ class WalletsHome extends StatelessWidget { myWalletProvider.listWallets = myWalletProvider.readAllWallets(currentChestNumber); + return WillPopScope( onWillPop: () { // myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index b00c805..febc0ed 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -1,3 +1,5 @@ +import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; @@ -34,6 +36,8 @@ class TransactionInProgress extends StatelessWidget { // Map jsonResult; final result = sub.transactionStatus; + // sub.spawnBlock(); + log.d(walletViewProvider.address!); final from = fromAddress ?? myWalletProvider.getDefaultWallet().name!; From 425677827cab70871358b1537f4b0a4231d141a4 Mon Sep 17 00:00:00 2001 From: poka Date: Wed, 31 Aug 2022 23:21:11 +0200 Subject: [PATCH 20/28] Add readme fo integration_tests --- integration_test/README.md | 128 +++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 integration_test/README.md diff --git a/integration_test/README.md b/integration_test/README.md new file mode 100644 index 0000000..769e50f --- /dev/null +++ b/integration_test/README.md @@ -0,0 +1,128 @@ +# Contexte des tests + +Chaque test est précédé par le lancement d'un noeud Duniter v2s en docker [dont voici le compose](https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/docker-compose.yml). + +Voici le yaml de configuration de la monnaie de test éphémère: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/data/gecko_tests.json + + +Voici le mnemonic de test utilisé: +`pipe paddle ketchup filter life ice feel embody glide quantum ride usage` + +Et les 5 premiers portefeuilles Gecko associés: +``` +test1: 5FeggKqw2AbnGZF9Y9WPM2QTgzENS3Hit94Ewgmzdg5a3LNa +test2: 5E4i8vcNjnrDp21Sbnp32WHm2gz8YP3GGFwmdpfg5bHd8Whb +test3: 5FhTLzXLNBPmtXtDBFECmD7fvKmTtTQDtvBTfVr97tachA1p +test4: 5DXJ4CusmCg8S1yF6JGVn4fxgk5oFx42WctXqHZ17mykgje5 +test5: 5Dq3giahrBfykJogPetZJ2jjSmhw49Fa7i6qKkseUvRJ2T3R +``` + +Seul les 4 premiers sont membres au démarrage. + +Voici le scénario de test principal que j'ai réalisé pour le moment + +Scénario 1 +- Changer le noeud Duniter pour se connecter au nœud local (l'ip local est récupéré automatiquement, car le nœud est sur le host (votre pc), alors que l'app est dans son émulateur) +- Importer le coffre de test +- Effectuer une transaction du Portefeuille 1 (test1) vers le portefeuille 5 (test5) +- Vérifier que les frais de créations de compte ont bien été prélevés +- Certifier test5 avec test1, test2 et test3 et vérifier qu'il deviens bien membre +- Créer 10 blocs, puis encore 10, puis 30 de plus et vérifier à chaque fois si le compte génère bien ses DU à la bonne valeur, réévaluation comprise au bloc 50. + +Des vérifications sur l'état du texte affiché à l'écran ou des widgets affichés ou non sont fait entre chaque étapes pour vérifier que tout ce passe toujours bien. +Si la moindre erreur intervient, le test s'arrête et vous informe de l'erreur en question. + +Voici le code du test contenant ce scénario: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/gecko_complete.dart + +Ce test dur environ 1 minutes et 15 seconds, compilation et lancement de nœud au démarrage inclus. + +Voici le rendu (attention ça va assez vite ^^) : + + +https://tube.p2p.legal/w/kMc5c8KnLi9BpwJrM4EnKX + +On remarque notamment que des blocs sont créés uniquement et directement après un extrinsic lancé depuis l'app + +--- + +# Tuto contributeurs + +**Il n'est nécessaire ni de connaître le code de Ğecko, ni de connaître Dart/flutter pour écrire un nouveau scénario de test !** + +Il vous suffit de comprendre par exemple cet extrait de code: + +``` +// Copy test mnemonic in clipboard +await clipCopy(testMnemonic); + +// Open screen import chest +await goKey(keyRestoreChest, duration: 0); + +// Tap on button to paste mnemonic +await goKey(keyPastMnemonic); + +// Tap on next button 4 times to skip 3 screen +await goKey(keyGoNext); +await goKey(keyGoNext); +await goKey(keyGoNext); +await goKey(keyGoNext); + +// Check if cached password checkbox is checked +final isCached = await isIconPresent(Icons.check_box); + +// If not, tap on to cache password +if (!isCached) await goKey(keyCachePassword, duration: 0); + +// Enter password +await enterText(keyPinForm, 'AAAAA', 0); + +// Check if string "Accéder à mon coffre" is present in screen +await waitFor('Accéder à mon coffre'); + +// Go to wallets home +await goKey(keyGoWalletsHome, duration: 0); + +// Check if string "ĞD" is present in screen +await waitFor('ĞD'); + +// Tap on add a new derivation button +await addDerivation(); + +// Tap on Wallet 5 +await goKey(keyOpenWallet(test5.address)); + +// Copy address of Wallet 5 +await goKey(keyCopyAddress); + +// Check if string "Cette adresse a été copié" is present in screen +await waitFor('Cette adresse a été copié'); + +// Pop screen 2 time to go back home +await goBack(); +await goBack(); + +// Create a new bloc (useless here, just to show you the method) +await spawnBlock(); + +// Check if string "y'a pas de lézard" is present in screen +await waitFor("y'a pas de lézard"); +``` + +Vous avez dans ce bout de code commenté tous ce dont vous avez besoin pour effectuer un test d'intégration dans Ğecko :slight_smile: + +Vous trouverez toutes les clés de widgets disponibles dans l'app dans ce fichier: https://git.duniter.org/clients/gecko/-/blob/end2EndTests/lib/models/widgets_keys.dart + +Ce sont ces clés qui vous permette d’interagir avec les widgets de l'app depuis votre test. + +Pour créer un nouveau test **à partir de zero**, voici la marche à suivre: +- Suivez [le readme](https://git.duniter.org/clients/gecko/-/blob/master/README.md) pour configurer votre environnement de développement et ainsi pouvoir lancer Ğecko en mode debug dans un émulateur. +- Créer un nouveau fichier pour votre test dans le dossier `integration_test` (ici nous l’appellerons `mon_test.dart`) +- Prenez exemple sur le fichier `gecko_complete.dart` pour écrire votre test +- Lancer un émulateur android (1 seul) +- Exécutez votre test ainsi: `./integration_test/launch_test.sh mon_test` + +Créer toute sorte de tests imaginable dans Ğecko est très utile pour éviter un maximum les régressions de bugs entre les différentes versions. + +Si vous avez envie de nous aider, que vous ne savez presque pas coder mais que vous êtes prêt à mettre un peu les mains dans la sauce, et que vous avez une idée de scénario à tester, alors n'hésitez pas, je répondrais à toutes vos questions :slight_smile: + +A noter que ces tests permettent de tester Gecko mais aussi partiellement Duniter et l'indexer d'une même pierre. From e01dea93296ad9a2c3cecda50621e60cd4dc2603 Mon Sep 17 00:00:00 2001 From: pokapow Date: Wed, 31 Aug 2022 23:22:23 +0200 Subject: [PATCH 21/28] =?UTF-8?q?Mettre=20=C3=A0=20jour=20integration=5Fte?= =?UTF-8?q?st/README.md?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- integration_test/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test/README.md b/integration_test/README.md index 769e50f..9583901 100644 --- a/integration_test/README.md +++ b/integration_test/README.md @@ -1,4 +1,4 @@ -# Contexte des tests +# Context des tests Chaque test est précédé par le lancement d'un noeud Duniter v2s en docker [dont voici le compose](https://git.duniter.org/clients/gecko/-/blob/end2EndTests/integration_test/duniter/docker-compose.yml). From ad9ee382d3eb15f4f738a35c68f27c01c1602b63 Mon Sep 17 00:00:00 2001 From: poka Date: Thu, 1 Sep 2022 04:51:51 +0200 Subject: [PATCH 22/28] wip: test onboarding --- integration_test/gecko_complete.dart | 2 +- integration_test/general_actions.dart | 64 +++++++++++++++++++ integration_test/launch_test.sh | 2 +- integration_test/multi_chests.dart | 17 +++++ integration_test/tests_utility.dart | 27 ++++++-- lib/models/widgets_keys.dart | 1 + lib/screens/home.dart | 2 +- lib/screens/onBoarding/10.dart | 2 + .../onBoarding/11_congratulations.dart | 15 +++-- lib/screens/onBoarding/5.dart | 4 +- lib/screens/onBoarding/6.dart | 1 + lib/screens/transaction_in_progress.dart | 2 - 12 files changed, 119 insertions(+), 20 deletions(-) create mode 100644 integration_test/multi_chests.dart diff --git a/integration_test/gecko_complete.dart b/integration_test/gecko_complete.dart index 7157f11..bcf1c23 100644 --- a/integration_test/gecko_complete.dart +++ b/integration_test/gecko_complete.dart @@ -134,6 +134,6 @@ Future certifyTest5() async { // Check UD reval await spawnBlock(until: 50); - await waitFor('509.35'); + await waitFor('509.36'); humanRead(5); } diff --git a/integration_test/general_actions.dart b/integration_test/general_actions.dart index cf8dfc1..8a734cd 100644 --- a/integration_test/general_actions.dart +++ b/integration_test/general_actions.dart @@ -3,6 +3,8 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; +import 'package:gecko/providers/generate_wallets.dart'; +import 'package:provider/provider.dart'; import 'tests_utility.dart'; // GENERAL ACTIONS @@ -83,6 +85,68 @@ Future restoreChest() async { await goBack(); } +Future onboardingNewChest() async { + final generateWalletProvider = + Provider.of(homeContext, listen: false); + // Open screen create new wallet + await tapKey(keyOnboardingNewChest); + + // Tap on next button 4 times to skip 3 screen + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await waitFor('7', exactMatch: true); + + final word41 = getWidgetText(keyMnemonicWord('4')); + + // Change 2 times mnemonic + await tapKey(keyGenerateMnemonic); + await tester.pumpAndSettle(); + final word42 = getWidgetText(keyMnemonicWord('4')); + expect(word41, isNot(word42)); + await tapKey(keyGenerateMnemonic, duration: 500); + await tester.pumpAndSettle(); + final word43 = getWidgetText(keyMnemonicWord('4')); + expect(word42, isNot(word43)); + + // Go next screen + await tapKey(keyGoNext); + await tester.pumpAndSettle(); + + // Enter asked word + final askedWordNumber = int.parse(getWidgetText(keyAskedWord)); + List mnemonic = generateWalletProvider.generatedMnemonic!.split(' '); + + final askedWord = mnemonic[askedWordNumber - 1]; + await enterText(keyInputWord, askedWord); + await waitFor('Continuer', exactMatch: true); + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await tapKey(keyGoNext); + await waitFor('AAAAA', exactMatch: true); + await tapKey(keyGoNext); + + // Check if cached password checkbox is checked + final isCached = await isIconPresent(Icons.check_box); + + // If not, tap on to cache password + if (!isCached) await tapKey(keyCachePassword, duration: 0); + + // Enter password + await enterText(keyPinForm, 'AAAAA', 0); + + // Check if string "Accéder à mon coffre" is present in screen + await waitFor('Accéder à mon coffre'); + + // Go to wallets home + await tapKey(keyGoWalletsHome, duration: 0); + + // Check if string "ĞD" is present in screen + await waitFor('Mon portefeuille co'); + await waitFor('0.0 $currencyName'); +} + Future addDerivation() async { await tapKey(keyAddDerivation); await waitFor('Portefeuille 5'); diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh index 9259b2f..44e9c02 100755 --- a/integration_test/launch_test.sh +++ b/integration_test/launch_test.sh @@ -17,7 +17,7 @@ docker-compose up -d cd ../.. # Start integration test -flutter test integration_test/$testName.dart +flutter test integration_test/$testName.dart && echo '0' > /tmp/geckoTestResult || echo '1' > /tmp/geckoTestResult # Reset .env echo "ip_address=127.0.0.1" > .env diff --git a/integration_test/multi_chests.dart b/integration_test/multi_chests.dart new file mode 100644 index 0000000..2b299db --- /dev/null +++ b/integration_test/multi_chests.dart @@ -0,0 +1,17 @@ +import 'package:flutter_dotenv/flutter_dotenv.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:gecko/models/widgets_keys.dart'; +import 'package:integration_test/integration_test.dart'; +import 'general_actions.dart'; +import 'tests_utility.dart'; + +void main() async { + IntegrationTestWidgetsFlutterBinding.ensureInitialized(); + await dotenv.load(); + + testWidgets('Onboarding and multi chest', (testerLoc) async { + tester = testerLoc; + await bkFastStart(false); + await onboardingNewChest(); + }, timeout: testTimeout()); +} diff --git a/integration_test/tests_utility.dart b/integration_test/tests_utility.dart index bb39cab..e8c60b7 100644 --- a/integration_test/tests_utility.dart +++ b/integration_test/tests_utility.dart @@ -265,13 +265,19 @@ Future _addImportAccount( Future bkDeleteAllWallets() async { final myWalletProvider = Provider.of(homeContext, listen: false); - if (myWalletProvider.listWallets.isNotEmpty) { - await myWalletProvider.deleteAllWallet(homeContext); + final isWalletsPresents = + await isPresent('Scanner un', timeout: const Duration(milliseconds: 300)); + if (isWalletsPresents) { + await walletBox.clear(); + await chestBox.clear(); + await configBox.delete('defaultWallet'); + await sub.deleteAllAccounts(); + myWalletProvider.pinCode = ''; myWalletProvider.rebuildWidget(); } } -Future bkFastStart() async { +Future bkFastStart([bool restoreChest = true]) async { // Start app and wait finish starting await startWait(); @@ -282,16 +288,23 @@ Future bkFastStart() async { // Delete all existing chests is exists await bkDeleteAllWallets(); - // Restore the test chest - await bkRestoreChest(); - await waitFor("y'a pas de lézard"); + if (restoreChest) { + // Restore the test chest + await bkRestoreChest(); + await waitFor("y'a pas de lézard"); + } } Future startWait() async { app.main(); await waitFor('Test starting...', reverse: true); await tester.pumpAndSettle(const Duration(milliseconds: 300)); - await sleep(2000); + await sleep(3000); +} + +String getWidgetText(Key key) { + final word4Finder = find.byKey(key); + return (word4Finder.evaluate().single.widget as Text).data!; } class TestWallet { diff --git a/lib/models/widgets_keys.dart b/lib/models/widgets_keys.dart index e10c39d..85bb691 100644 --- a/lib/models/widgets_keys.dart +++ b/lib/models/widgets_keys.dart @@ -16,6 +16,7 @@ const keyDrawerMenu = Key('keyDrawerMenu'); const keyOpenWalletsHomme = Key('keyOpenWalletsHomme'); const keyOpenSearch = Key('keyOpenSearch'); const keyRestoreChest = Key('keyRestoreChest'); +const keyOnboardingNewChest = Key('keyOnboardingNewChest'); // Wallets home const keyImportG1v1 = Key('keyImportG1v1'); diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 8850781..2516f86 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -538,7 +538,7 @@ Widget welcomeHome(context) { SizedBox( width: 410, height: 70, - child: ElevatedButton( + child: ElevatedButton(key: keyOnboardingNewChest, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index 82df70c..e3150a1 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -1,6 +1,7 @@ // ignore_for_file: file_names import 'dart:async'; +import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -228,6 +229,7 @@ class OnboardingStepTen extends StatelessWidget { generateWalletProvider.generatedMnemonic = ''; myWalletProvider.resetPinCode(); + // sleep(const Duration(milliseconds: 500)); Navigator.push( context, FaderTransition( diff --git a/lib/screens/onBoarding/11_congratulations.dart b/lib/screens/onBoarding/11_congratulations.dart index 11f6b29..de1747d 100644 --- a/lib/screens/onBoarding/11_congratulations.dart +++ b/lib/screens/onBoarding/11_congratulations.dart @@ -1,5 +1,7 @@ // ignore_for_file: file_names +import 'dart:io'; + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; @@ -62,13 +64,12 @@ Widget finishButton(BuildContext context) { onPrimary: Colors.white, // foreground ), onPressed: () { - Navigator.pushAndRemoveUntil( - context, - MaterialPageRoute(builder: (context) { - return const WalletsHome(); - }), - ModalRoute.withName('/'), - ); + // sleep(const Duration(milliseconds: 50)); + Navigator.popUntil(homeContext, ModalRoute.withName('/')); + // sleep(const Duration(milliseconds: 500)); + Navigator.pushNamed(homeContext, '/mywallets'); + // Navigator.pushNamedAndRemoveUntil( + // homeContext, '/mywallets', ModalRoute.withName('/')); }, child: Text("accessMyChest".tr(), style: diff --git a/lib/screens/onBoarding/5.dart b/lib/screens/onBoarding/5.dart index 55e2466..dd4907c 100644 --- a/lib/screens/onBoarding/5.dart +++ b/lib/screens/onBoarding/5.dart @@ -102,7 +102,8 @@ class _ChooseChestState extends State { SizedBox(height: 22 * ratio), nextButton( context, "iNotedMyMnemonic".tr(), false, widget.skipIntro), - SizedBox(height: 35 * ratio), + const Spacer(), + // SizedBox(height: 35 * ratio), ]), CommonElements().offlineInfo(context), ]), @@ -231,6 +232,7 @@ Widget nextButton( width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( + key: keyGoNext, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/onBoarding/6.dart b/lib/screens/onBoarding/6.dart index 309ae29..2c8562b 100644 --- a/lib/screens/onBoarding/6.dart +++ b/lib/screens/onBoarding/6.dart @@ -225,6 +225,7 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) { width: 380 * ratio, height: 60 * ratio, child: ElevatedButton( + key: keyGoNext, style: ElevatedButton.styleFrom( elevation: 4, primary: orangeC, // background diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index febc0ed..9c8b261 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -1,5 +1,3 @@ -import 'dart:io'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; From 7491b9b4896e37582cc83da149e69115d546cbe8 Mon Sep 17 00:00:00 2001 From: Hugo Trentesaux Date: Thu, 1 Sep 2022 16:43:55 +0200 Subject: [PATCH 23/28] Migration docker compose --- integration_test/launch_test.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/integration_test/launch_test.sh b/integration_test/launch_test.sh index 44e9c02..7f130c0 100755 --- a/integration_test/launch_test.sh +++ b/integration_test/launch_test.sh @@ -11,9 +11,9 @@ echo "ip_address=$ip_address" > .env ## Start local Duniter node cd integration_test/duniter -docker-compose down +docker compose down rm -rf data/chains -docker-compose up -d +docker compose up -d cd ../.. # Start integration test @@ -24,6 +24,6 @@ echo "ip_address=127.0.0.1" > .env # Stop Duniter cd integration_test/duniter -docker-compose down +docker compose down From 58572a5e0ec47652e23996de4101171450519c7e Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 5 Sep 2022 04:15:27 +0200 Subject: [PATCH 24/28] migrate flutter 3.3.0 --- integration_test/multi_chests.dart | 1 - lib/providers/generate_wallets.dart | 1 - lib/providers/substrate_sdk.dart | 1 - lib/providers/wallet_options.dart | 14 +++---- lib/screens/activity.dart | 3 +- lib/screens/avatar_fullscreen.dart | 7 +--- lib/screens/common_elements.dart | 4 +- lib/screens/home.dart | 4 +- lib/screens/myWallets/change_pin.dart | 12 ++---- lib/screens/myWallets/choose_chest.dart | 4 +- lib/screens/myWallets/choose_wallet.dart | 7 +--- lib/screens/myWallets/custom_derivations.dart | 4 +- lib/screens/myWallets/import_g1_v1.dart | 4 +- lib/screens/myWallets/migrate_identity.dart | 4 +- lib/screens/myWallets/restore_chest.dart | 8 +--- lib/screens/myWallets/show_seed.dart | 13 ++---- .../myWallets/transaction_comment.dart | 3 +- lib/screens/myWallets/unlocking_wallet.dart | 3 +- lib/screens/myWallets/wallet_options.dart | 12 ++---- lib/screens/myWallets/wallets_home.dart | 4 +- lib/screens/onBoarding/10.dart | 3 +- .../onBoarding/11_congratulations.dart | 8 +--- lib/screens/onBoarding/5.dart | 9 +---- lib/screens/onBoarding/6.dart | 7 ++-- lib/screens/onBoarding/9.dart | 5 +-- lib/screens/qrcode_fullscreen.dart | 3 +- lib/screens/search.dart | 4 +- lib/screens/settings.dart | 1 - lib/screens/transaction_in_progress.dart | 5 +-- lib/screens/wallet_view.dart | 4 +- pubspec.lock | 40 +++++++++---------- 31 files changed, 70 insertions(+), 132 deletions(-) diff --git a/integration_test/multi_chests.dart b/integration_test/multi_chests.dart index 2b299db..a81742e 100644 --- a/integration_test/multi_chests.dart +++ b/integration_test/multi_chests.dart @@ -1,6 +1,5 @@ import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:gecko/models/widgets_keys.dart'; import 'package:integration_test/integration_test.dart'; import 'general_actions.dart'; import 'tests_utility.dart'; diff --git a/lib/providers/generate_wallets.dart b/lib/providers/generate_wallets.dart index 43355a7..0d81211 100644 --- a/lib/providers/generate_wallets.dart +++ b/lib/providers/generate_wallets.dart @@ -1,5 +1,4 @@ import 'dart:math'; -import 'dart:typed_data'; import 'package:durt/durt.dart' as durt; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; diff --git a/lib/providers/substrate_sdk.dart b/lib/providers/substrate_sdk.dart index af1bbca..3955cf4 100644 --- a/lib/providers/substrate_sdk.dart +++ b/lib/providers/substrate_sdk.dart @@ -1,6 +1,5 @@ // ignore_for_file: use_build_context_synchronously -import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; diff --git a/lib/providers/wallet_options.dart b/lib/providers/wallet_options.dart index ac2f106..3438bec 100644 --- a/lib/providers/wallet_options.dart +++ b/lib/providers/wallet_options.dart @@ -137,7 +137,7 @@ class WalletOptionsProvider with ChangeNotifier { DuniterIndexer duniterIndexer = Provider.of(context, listen: false); - _showText(String text, + showText(String text, [double size = 18, bool bold = false, bool smooth = true]) { log.d('$address $text'); return AnimatedFadeOutIn( @@ -163,16 +163,16 @@ class WalletOptionsProvider with ChangeNotifier { switch (snapshot.data.toString()) { case 'noid': { - return _showText('noIdentity'.tr()); + return showText('noIdentity'.tr()); } case 'Created': { - return _showText('identityCreated'.tr()); + return showText('identityCreated'.tr()); } case 'ConfirmedByOwner': { return isOwner - ? _showText('identityConfirmed'.tr()) + ? showText('identityConfirmed'.tr()) : duniterIndexer.getNameByAddress( context, address, @@ -187,7 +187,7 @@ class WalletOptionsProvider with ChangeNotifier { case 'Validated': { return isOwner - ? _showText('memberValidated'.tr(), 18, true) + ? showText('memberValidated'.tr(), 18, true) : duniterIndexer.getNameByAddress( context, address, @@ -201,11 +201,11 @@ class WalletOptionsProvider with ChangeNotifier { case 'expired': { - return _showText('identityExpired'.tr()); + return showText('identityExpired'.tr()); } } return SizedBox( - child: _showText('', 18, false, false), + child: showText('', 18, false, false), ); }); }); diff --git a/lib/screens/activity.dart b/lib/screens/activity.dart index 5635c49..2be757d 100644 --- a/lib/screens/activity.dart +++ b/lib/screens/activity.dart @@ -1,3 +1,5 @@ +// ignore_for_file: must_be_immutable + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; @@ -13,7 +15,6 @@ import 'package:gecko/screens/wallet_view.dart'; import 'package:graphql_flutter/graphql_flutter.dart'; import 'package:provider/provider.dart'; -// ignore: must_be_immutable class ActivityScreen extends StatelessWidget with ChangeNotifier { ActivityScreen({required this.address, this.avatar, this.username, Key? key}) : super(key: key); diff --git a/lib/screens/avatar_fullscreen.dart b/lib/screens/avatar_fullscreen.dart index 682e290..ef87be1 100644 --- a/lib/screens/avatar_fullscreen.dart +++ b/lib/screens/avatar_fullscreen.dart @@ -1,14 +1,9 @@ import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; -// import 'package:gecko/models/home.dart'; -// import 'package:provider/provider.dart'; -// ignore: must_be_immutable class AvatarFullscreen extends StatelessWidget { - TextEditingController tplController = TextEditingController(); - - AvatarFullscreen(this.avatar, {this.title, this.color, Key? key}) + const AvatarFullscreen(this.avatar, {this.title, this.color, Key? key}) : super(key: key); final Image? avatar; final String? title; diff --git a/lib/screens/common_elements.dart b/lib/screens/common_elements.dart index d077384..0b88edb 100644 --- a/lib/screens/common_elements.dart +++ b/lib/screens/common_elements.dart @@ -65,9 +65,7 @@ class CommonElements { child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, backgroundColor: orangeC, elevation: 4, // foreground ), onPressed: () { Navigator.push( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index 2516f86..cc51af0 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -540,9 +540,7 @@ Widget welcomeHome(context) { height: 70, child: ElevatedButton(key: keyOnboardingNewChest, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.push( diff --git a/lib/screens/myWallets/change_pin.dart b/lib/screens/myWallets/change_pin.dart index 26b3f4c..be5a3bc 100644 --- a/lib/screens/myWallets/change_pin.dart +++ b/lib/screens/myWallets/change_pin.dart @@ -1,4 +1,4 @@ -// ignore_for_file: use_build_context_synchronously +// ignore_for_file: use_build_context_synchronously, must_be_immutable import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; @@ -10,11 +10,9 @@ import 'package:gecko/models/wallet_data.dart'; import 'package:gecko/providers/my_wallets.dart'; import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/screens/myWallets/unlocking_wallet.dart'; -import 'dart:io'; import 'package:provider/provider.dart'; -// ignore: must_be_immutable class ChangePinScreen extends StatelessWidget with ChangeNotifier { ChangePinScreen( {Key? keyMyWallets, @@ -23,9 +21,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier { : super(key: keyMyWallets); final String? walletName; final MyWalletsProvider walletProvider; - Directory? appPath; - TextEditingController newPin = TextEditingController(); + final TextEditingController newPin = TextEditingController(); @override Widget build(BuildContext context) { @@ -102,9 +99,8 @@ class ChangePinScreen extends StatelessWidget with ChangeNotifier { height: 50, child: ElevatedButton( style: ElevatedButton.styleFrom( - elevation: 12, - primary: Colors.green[400], //smoothYellow, // background - onPrimary: Colors.black, // foreground + foregroundColor: Colors.black, elevation: 12, + backgroundColor: Colors.green[400], // foreground ), onPressed: () async { WalletData defaultWallet = diff --git a/lib/screens/myWallets/choose_chest.dart b/lib/screens/myWallets/choose_chest.dart index 4974f2c..ee99910 100644 --- a/lib/screens/myWallets/choose_chest.dart +++ b/lib/screens/myWallets/choose_chest.dart @@ -23,7 +23,6 @@ class ChooseChest extends StatefulWidget { } } -// ignore: must_be_immutable class _ChooseChestState extends State { TextEditingController tplController = TextEditingController(); CarouselController buttonCarouselController = CarouselController(); @@ -112,8 +111,7 @@ class _ChooseChestState extends State { height: 70, child: ElevatedButton( style: ElevatedButton.styleFrom( - primary: orangeC, // background - onPrimary: Colors.black, // foreground + foregroundColor: Colors.black, backgroundColor: orangeC, // foreground ), onPressed: () async { await configBox.put('currentChest', currentChest); diff --git a/lib/screens/myWallets/choose_wallet.dart b/lib/screens/myWallets/choose_wallet.dart index 8f4d73a..a5772de 100644 --- a/lib/screens/myWallets/choose_wallet.dart +++ b/lib/screens/myWallets/choose_wallet.dart @@ -1,4 +1,4 @@ -// ignore_for_file: use_build_context_synchronously +// ignore_for_file: use_build_context_synchronously, must_be_immutable import 'dart:io'; @@ -16,7 +16,6 @@ import 'package:provider/provider.dart'; // import 'package:gecko/models/home.dart'; // import 'package:provider/provider.dart'; -// ignore: must_be_immutable class ChooseWalletScreen extends StatelessWidget { ChooseWalletScreen({Key? key, required this.pin}) : super(key: key); final String pin; @@ -49,9 +48,7 @@ class ChooseWalletScreen extends StatelessWidget { child: ElevatedButton( key: keyConfirm, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () async { await sub.setCurrentWallet(selectedWallet!); diff --git a/lib/screens/myWallets/custom_derivations.dart b/lib/screens/myWallets/custom_derivations.dart index a5d264d..43d3493 100644 --- a/lib/screens/myWallets/custom_derivations.dart +++ b/lib/screens/myWallets/custom_derivations.dart @@ -107,9 +107,7 @@ class _CustomDerivationState extends State { height: 70, child: ElevatedButton( style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () async { WalletData? defaultWallet = diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index 2683757..0e40a35 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -239,9 +239,7 @@ class ImportG1v1 extends StatelessWidget { child: ElevatedButton( key: keyConfirm, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { diff --git a/lib/screens/myWallets/migrate_identity.dart b/lib/screens/myWallets/migrate_identity.dart index b8fa00d..12137e9 100644 --- a/lib/screens/myWallets/migrate_identity.dart +++ b/lib/screens/myWallets/migrate_identity.dart @@ -188,9 +188,7 @@ class MigrateIdentityScreen extends StatelessWidget { height: 60 * ratio, child: ElevatedButton( style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { diff --git a/lib/screens/myWallets/restore_chest.dart b/lib/screens/myWallets/restore_chest.dart index 4ec6d68..6f98b45 100644 --- a/lib/screens/myWallets/restore_chest.dart +++ b/lib/screens/myWallets/restore_chest.dart @@ -94,9 +94,7 @@ class RestoreChest extends StatelessWidget { child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () async { if (await sub @@ -134,9 +132,7 @@ class RestoreChest extends StatelessWidget { child: ElevatedButton( key: keyPastMnemonic, style: ElevatedButton.styleFrom( - elevation: 4, - primary: yellowC, // background - onPrimary: Colors.black, // foreground + foregroundColor: Colors.black, elevation: 4, backgroundColor: yellowC, // foreground ), onPressed: () { genW.pasteMnemonic(context); diff --git a/lib/screens/myWallets/show_seed.dart b/lib/screens/myWallets/show_seed.dart index 002bed1..92a454b 100644 --- a/lib/screens/myWallets/show_seed.dart +++ b/lib/screens/myWallets/show_seed.dart @@ -1,4 +1,3 @@ -import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; @@ -74,12 +73,10 @@ class ShowSeed extends StatelessWidget { height: 40, child: ElevatedButton( style: ElevatedButton.styleFrom( - shape: RoundedRectangleBorder( + foregroundColor: Colors.black, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), - ), - elevation: 1, - primary: orangeC, // background - onPrimary: Colors.black, // foreground + ), backgroundColor: orangeC, + elevation: 1, // foreground ), onPressed: () { Clipboard.setData( @@ -124,9 +121,7 @@ class ShowSeed extends StatelessWidget { height: 60 * ratio, child: ElevatedButton( style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.pop(context); diff --git a/lib/screens/myWallets/transaction_comment.dart b/lib/screens/myWallets/transaction_comment.dart index 3632f65..7312324 100644 --- a/lib/screens/myWallets/transaction_comment.dart +++ b/lib/screens/myWallets/transaction_comment.dart @@ -1,3 +1,5 @@ +// ignore_for_file: must_be_immutable + import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; @@ -5,7 +7,6 @@ import 'package:flutter/material.dart'; // import 'package:gecko/models/home.dart'; // import 'package:provider/provider.dart'; -// ignore: must_be_immutable class TransactionCommentScreen extends StatelessWidget { TextEditingController tplController = TextEditingController(); diff --git a/lib/screens/myWallets/unlocking_wallet.dart b/lib/screens/myWallets/unlocking_wallet.dart index 3011588..04c23ab 100644 --- a/lib/screens/myWallets/unlocking_wallet.dart +++ b/lib/screens/myWallets/unlocking_wallet.dart @@ -1,3 +1,5 @@ +// ignore_for_file: must_be_immutable + import 'dart:async'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; @@ -14,7 +16,6 @@ import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:provider/provider.dart'; import 'package:gecko/globals.dart'; -// ignore: must_be_immutable class UnlockingWallet extends StatelessWidget { UnlockingWallet({Key? keyUnlockWallet, required this.wallet}) : super(key: keyUnlockWallet); diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index f213449..bdb3799 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -299,9 +299,7 @@ class WalletOptions extends StatelessWidget { child: ElevatedButton( key: keyConfirmIdentity, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () { walletProvider.confirmIdentityPopup(context); @@ -365,12 +363,10 @@ class WalletOptions extends StatelessWidget { height: 40, child: ElevatedButton( style: ElevatedButton.styleFrom( - shape: RoundedRectangleBorder( + foregroundColor: Colors.black, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), - ), - elevation: 1, - primary: orangeC, // background - onPrimary: Colors.black, // foreground + ), backgroundColor: orangeC, + elevation: 1, // foreground ), onPressed: () { Clipboard.setData( diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index 7e452bf..ef355d2 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -88,9 +88,7 @@ class WalletsHome extends StatelessWidget { height: 60, ), style: ElevatedButton.styleFrom( - elevation: 2, - primary: floattingYellow, // background - onPrimary: Colors.black, // foreground + foregroundColor: Colors.black, elevation: 2, backgroundColor: floattingYellow, // foreground ), onPressed: () => Navigator.push( context, diff --git a/lib/screens/onBoarding/10.dart b/lib/screens/onBoarding/10.dart index e3150a1..4b7b144 100644 --- a/lib/screens/onBoarding/10.dart +++ b/lib/screens/onBoarding/10.dart @@ -1,7 +1,7 @@ // ignore_for_file: file_names +// ignore_for_file: must_be_immutable import 'dart:async'; -import 'dart:io'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; @@ -18,7 +18,6 @@ import 'package:gecko/screens/onBoarding/11_congratulations.dart'; import 'package:pin_code_fields/pin_code_fields.dart'; import 'package:provider/provider.dart'; -// ignore: must_be_immutable class OnboardingStepTen extends StatelessWidget { OnboardingStepTen({Key? validationKey, this.scanDerivation = false}) : super(key: validationKey); diff --git a/lib/screens/onBoarding/11_congratulations.dart b/lib/screens/onBoarding/11_congratulations.dart index de1747d..61bd8b0 100644 --- a/lib/screens/onBoarding/11_congratulations.dart +++ b/lib/screens/onBoarding/11_congratulations.dart @@ -1,16 +1,12 @@ // ignore_for_file: file_names -import 'dart:io'; - import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; import 'package:flutter/material.dart'; import 'package:gecko/globals.dart'; import 'package:gecko/models/widgets_keys.dart'; import 'package:gecko/screens/common_elements.dart'; -import 'package:gecko/screens/myWallets/wallets_home.dart'; -// ignore: must_be_immutable class OnboardingStepEleven extends StatelessWidget { const OnboardingStepEleven({Key? key}) : super(key: key); @@ -59,9 +55,7 @@ Widget finishButton(BuildContext context) { child: ElevatedButton( key: keyGoWalletsHome, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () { // sleep(const Duration(milliseconds: 50)); diff --git a/lib/screens/onBoarding/5.dart b/lib/screens/onBoarding/5.dart index dd4907c..f82c2e9 100644 --- a/lib/screens/onBoarding/5.dart +++ b/lib/screens/onBoarding/5.dart @@ -83,9 +83,7 @@ class _ChooseChestState extends State { child: ElevatedButton( key: keyGenerateMnemonic, style: ElevatedButton.styleFrom( - elevation: 4, - primary: const Color(0xffFFD58D), - onPrimary: Colors.black, // foreground + foregroundColor: Colors.black, elevation: 4, backgroundColor: const Color(0xffFFD58D), // foreground ), onPressed: () { // _generateWalletProvider.reloadBuild(); @@ -183,7 +181,6 @@ Widget arrayCell(dataWord) { ); } -// ignore: must_be_immutable class PrintWallet extends StatelessWidget { const PrintWallet(this.sentence, {Key? key}) : super(key: key); @@ -234,9 +231,7 @@ Widget nextButton( child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () { generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt(); diff --git a/lib/screens/onBoarding/6.dart b/lib/screens/onBoarding/6.dart index 2c8562b..8e3a624 100644 --- a/lib/screens/onBoarding/6.dart +++ b/lib/screens/onBoarding/6.dart @@ -1,4 +1,5 @@ // ignore_for_file: file_names +// ignore_for_file: must_be_immutable import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/services.dart'; @@ -11,7 +12,6 @@ import 'package:gecko/screens/onBoarding/7.dart'; import 'package:gecko/screens/onBoarding/9.dart'; import 'package:provider/provider.dart'; -// ignore: must_be_immutable class OnboardingStepSix extends StatelessWidget { OnboardingStepSix( {Key? key, required this.skipIntro, required this.generatedMnemonic}) @@ -227,9 +227,8 @@ Widget nextButton(BuildContext context, String text, nextScreen, bool isFast) { child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.push( diff --git a/lib/screens/onBoarding/9.dart b/lib/screens/onBoarding/9.dart index a2b83ea..6958157 100644 --- a/lib/screens/onBoarding/9.dart +++ b/lib/screens/onBoarding/9.dart @@ -9,7 +9,6 @@ import 'package:gecko/screens/common_elements.dart'; import 'package:gecko/screens/onBoarding/10.dart'; import 'package:provider/provider.dart'; -// ignore: must_be_immutable class OnboardingStepNine extends StatelessWidget { const OnboardingStepNine({Key? key, this.scanDerivation = false}) : super(key: key); @@ -82,9 +81,7 @@ class OnboardingStepNine extends StatelessWidget { child: ElevatedButton( key: keyChangePin, style: ElevatedButton.styleFrom( - elevation: 4, - primary: const Color(0xffFFD58D), - onPrimary: Colors.black, // foreground + foregroundColor: Colors.black, elevation: 4, backgroundColor: const Color(0xffFFD58D), // foreground ), onPressed: () { generateWalletProvider.changePinCode( diff --git a/lib/screens/qrcode_fullscreen.dart b/lib/screens/qrcode_fullscreen.dart index c789e01..4ad6e6d 100644 --- a/lib/screens/qrcode_fullscreen.dart +++ b/lib/screens/qrcode_fullscreen.dart @@ -1,3 +1,5 @@ +// ignore_for_file: must_be_immutable + import 'package:flutter/services.dart'; import 'package:gecko/globals.dart'; import 'package:flutter/material.dart'; @@ -6,7 +8,6 @@ import 'package:qr_flutter/qr_flutter.dart'; // import 'package:gecko/models/home.dart'; // import 'package:provider/provider.dart'; -// ignore: must_be_immutable class QrCodeFullscreen extends StatelessWidget { TextEditingController tplController = TextEditingController(); diff --git a/lib/screens/search.dart b/lib/screens/search.dart index ff3c6d7..a28a7dc 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -95,9 +95,7 @@ class SearchScreen extends StatelessWidget { child: ElevatedButton( key: keyConfirmSearch, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: searchProvider.searchController.text.length >= 2 ? () { diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 5c9e325..94fee97 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -11,7 +11,6 @@ import 'package:polkawallet_sdk/api/types/networkParams.dart'; import 'package:provider/provider.dart'; // import 'package:dropdown_button2/dropdown_button2.dart'; -// ignore: must_be_immutable class SettingsScreen extends StatelessWidget { final MyWalletsProvider _myWallets = MyWalletsProvider(); diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index 9c8b261..6bd77e4 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -10,7 +10,6 @@ import 'package:provider/provider.dart'; // import 'package:gecko/models/home.dart'; // import 'package:provider/provider.dart'; -// ignore: must_be_immutable class TransactionInProgress extends StatelessWidget { const TransactionInProgress( {Key? key, this.transType = 'pay', this.fromAddress, this.toAddress}) @@ -268,9 +267,7 @@ class TransactionInProgress extends StatelessWidget { child: ElevatedButton( key: keyCloseTransactionScreen, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.pop(context); diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 6089693..27f971b 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -626,9 +626,7 @@ class WalletViewScreen extends StatelessWidget { child: ElevatedButton( key: keyConfirmPayment, style: ElevatedButton.styleFrom( - elevation: 4, - primary: orangeC, // background - onPrimary: Colors.white, // foreground + foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { diff --git a/pubspec.lock b/pubspec.lock index 6fc8368..661ba8a 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -21,7 +21,7 @@ packages: name: archive url: "https://pub.dartlang.org" source: hosted - version: "3.1.11" + version: "3.3.0" args: dependency: transitive description: @@ -42,7 +42,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.8.2" + version: "2.9.0" auth_header: dependency: transitive description: @@ -161,7 +161,7 @@ packages: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" charcode: dependency: transitive description: @@ -182,7 +182,7 @@ packages: name: clock url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" code_builder: dependency: transitive description: @@ -259,7 +259,7 @@ packages: name: coverage url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.5.0" cross_file: dependency: transitive description: @@ -273,7 +273,7 @@ packages: name: crypto url: "https://pub.dartlang.org" source: hosted - version: "3.0.1" + version: "3.0.2" dart_style: dependency: transitive description: @@ -343,7 +343,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" fast_base58: dependency: "direct main" description: @@ -791,14 +791,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.11" + version: "0.12.12" material_color_utilities: dependency: transitive description: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.4" + version: "0.1.5" matrix4_transform: dependency: transitive description: @@ -812,7 +812,7 @@ packages: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.7.0" + version: "1.8.0" mime: dependency: transitive description: @@ -910,7 +910,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" path_drawing: dependency: transitive description: @@ -1311,7 +1311,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.2" + version: "1.9.0" stack_trace: dependency: transitive description: @@ -1339,42 +1339,42 @@ packages: name: string_scanner url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.1.1" sync_http: dependency: "direct main" description: name: sync_http url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.3.1" term_glyph: dependency: transitive description: name: term_glyph url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.2.1" test: dependency: "direct main" description: name: test url: "https://pub.dartlang.org" source: hosted - version: "1.21.1" + version: "1.21.4" test_api: dependency: transitive description: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.9" + version: "0.4.12" test_core: dependency: transitive description: name: test_core url: "https://pub.dartlang.org" source: hosted - version: "0.4.13" + version: "0.4.16" timing: dependency: transitive description: @@ -1395,7 +1395,7 @@ packages: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.3.1" universal_io: dependency: transitive description: @@ -1430,7 +1430,7 @@ packages: name: vm_service url: "https://pub.dartlang.org" source: hosted - version: "8.2.2" + version: "9.0.0" watcher: dependency: transitive description: From d9222fe6ba7a59789189d6e6cb7d2bfff4665a20 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 5 Sep 2022 08:09:12 +0200 Subject: [PATCH 25/28] add todo fix random bad widget ancestor after onboarding --- .../duniter/data/gecko_tests.json | 0 integration_test/general_actions.dart | 1 + .../onBoarding/11_congratulations.dart | 21 ++++++++++++++----- 3 files changed, 17 insertions(+), 5 deletions(-) mode change 100644 => 100755 integration_test/duniter/data/gecko_tests.json diff --git a/integration_test/duniter/data/gecko_tests.json b/integration_test/duniter/data/gecko_tests.json old mode 100644 new mode 100755 diff --git a/integration_test/general_actions.dart b/integration_test/general_actions.dart index 8a734cd..612675a 100644 --- a/integration_test/general_actions.dart +++ b/integration_test/general_actions.dart @@ -145,6 +145,7 @@ Future onboardingNewChest() async { // Check if string "ĞD" is present in screen await waitFor('Mon portefeuille co'); await waitFor('0.0 $currencyName'); + // await waitFor('Scanner un'); } Future addDerivation() async { diff --git a/lib/screens/onBoarding/11_congratulations.dart b/lib/screens/onBoarding/11_congratulations.dart index 61bd8b0..d372db2 100644 --- a/lib/screens/onBoarding/11_congratulations.dart +++ b/lib/screens/onBoarding/11_congratulations.dart @@ -55,13 +55,24 @@ Widget finishButton(BuildContext context) { child: ElevatedButton( key: keyGoWalletsHome, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { - // sleep(const Duration(milliseconds: 50)); - Navigator.popUntil(homeContext, ModalRoute.withName('/')); - // sleep(const Duration(milliseconds: 500)); - Navigator.pushNamed(homeContext, '/mywallets'); + //TODO: fix bad widget ancestor when pupUntil (multi_chest test failed) + + // Navigator.popUntil(homeContext, ModalRoute.withName('/')); + // Navigator.of(homeContext, rootNavigator: true) + // .popUntil(ModalRoute.withName('/')); + // while (Navigator.of(homeContext).canPop()) { + // Navigator.of(homeContext).pop(); + // } + + // Navigator.pushNamed(homeContext, '/mywallets'); + + Navigator.pushNamedAndRemoveUntil( + context, '/mywallets', (route) => route.isFirst); + // Navigator.pushNamedAndRemoveUntil( // homeContext, '/mywallets', ModalRoute.withName('/')); }, From 03a9f1ea19bec02fdbe2f3d7cb69595bf6cdd90a Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 5 Sep 2022 08:12:24 +0200 Subject: [PATCH 26/28] fix flutter format --- lib/screens/common_elements.dart | 3 ++- lib/screens/home.dart | 6 ++++-- lib/screens/myWallets/choose_chest.dart | 3 ++- lib/screens/myWallets/choose_wallet.dart | 3 ++- lib/screens/myWallets/custom_derivations.dart | 3 ++- lib/screens/myWallets/import_g1_v1.dart | 3 ++- lib/screens/myWallets/migrate_identity.dart | 3 ++- lib/screens/myWallets/restore_chest.dart | 6 ++++-- lib/screens/myWallets/show_seed.dart | 9 ++++++--- lib/screens/myWallets/wallet_options.dart | 9 ++++++--- lib/screens/myWallets/wallets_home.dart | 4 ++-- lib/screens/onBoarding/5.dart | 6 ++++-- lib/screens/onBoarding/9.dart | 5 ++++- lib/screens/search.dart | 3 ++- lib/screens/transaction_in_progress.dart | 3 ++- lib/screens/wallet_view.dart | 3 ++- 16 files changed, 48 insertions(+), 24 deletions(-) diff --git a/lib/screens/common_elements.dart b/lib/screens/common_elements.dart index 0b88edb..71a8278 100644 --- a/lib/screens/common_elements.dart +++ b/lib/screens/common_elements.dart @@ -65,7 +65,8 @@ class CommonElements { child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, backgroundColor: orangeC, elevation: 4, // foreground + foregroundColor: Colors.white, backgroundColor: orangeC, + elevation: 4, // foreground ), onPressed: () { Navigator.push( diff --git a/lib/screens/home.dart b/lib/screens/home.dart index cc51af0..221e19e 100644 --- a/lib/screens/home.dart +++ b/lib/screens/home.dart @@ -538,9 +538,11 @@ Widget welcomeHome(context) { SizedBox( width: 410, height: 70, - child: ElevatedButton(key: keyOnboardingNewChest, + child: ElevatedButton( + key: keyOnboardingNewChest, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.push( diff --git a/lib/screens/myWallets/choose_chest.dart b/lib/screens/myWallets/choose_chest.dart index ee99910..e91676d 100644 --- a/lib/screens/myWallets/choose_chest.dart +++ b/lib/screens/myWallets/choose_chest.dart @@ -111,7 +111,8 @@ class _ChooseChestState extends State { height: 70, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, backgroundColor: orangeC, // foreground + foregroundColor: Colors.black, + backgroundColor: orangeC, // foreground ), onPressed: () async { await configBox.put('currentChest', currentChest); diff --git a/lib/screens/myWallets/choose_wallet.dart b/lib/screens/myWallets/choose_wallet.dart index a5772de..50c4eab 100644 --- a/lib/screens/myWallets/choose_wallet.dart +++ b/lib/screens/myWallets/choose_wallet.dart @@ -48,7 +48,8 @@ class ChooseWalletScreen extends StatelessWidget { child: ElevatedButton( key: keyConfirm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () async { await sub.setCurrentWallet(selectedWallet!); diff --git a/lib/screens/myWallets/custom_derivations.dart b/lib/screens/myWallets/custom_derivations.dart index 43d3493..be97443 100644 --- a/lib/screens/myWallets/custom_derivations.dart +++ b/lib/screens/myWallets/custom_derivations.dart @@ -107,7 +107,8 @@ class _CustomDerivationState extends State { height: 70, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () async { WalletData? defaultWallet = diff --git a/lib/screens/myWallets/import_g1_v1.dart b/lib/screens/myWallets/import_g1_v1.dart index 0e40a35..052754c 100644 --- a/lib/screens/myWallets/import_g1_v1.dart +++ b/lib/screens/myWallets/import_g1_v1.dart @@ -239,7 +239,8 @@ class ImportG1v1 extends StatelessWidget { child: ElevatedButton( key: keyConfirm, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { diff --git a/lib/screens/myWallets/migrate_identity.dart b/lib/screens/myWallets/migrate_identity.dart index 12137e9..535f6d3 100644 --- a/lib/screens/myWallets/migrate_identity.dart +++ b/lib/screens/myWallets/migrate_identity.dart @@ -188,7 +188,8 @@ class MigrateIdentityScreen extends StatelessWidget { height: 60 * ratio, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { diff --git a/lib/screens/myWallets/restore_chest.dart b/lib/screens/myWallets/restore_chest.dart index 6f98b45..92e5440 100644 --- a/lib/screens/myWallets/restore_chest.dart +++ b/lib/screens/myWallets/restore_chest.dart @@ -94,7 +94,8 @@ class RestoreChest extends StatelessWidget { child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () async { if (await sub @@ -132,7 +133,8 @@ class RestoreChest extends StatelessWidget { child: ElevatedButton( key: keyPastMnemonic, style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 4, backgroundColor: yellowC, // foreground + foregroundColor: Colors.black, elevation: 4, + backgroundColor: yellowC, // foreground ), onPressed: () { genW.pasteMnemonic(context); diff --git a/lib/screens/myWallets/show_seed.dart b/lib/screens/myWallets/show_seed.dart index 92a454b..1bd1433 100644 --- a/lib/screens/myWallets/show_seed.dart +++ b/lib/screens/myWallets/show_seed.dart @@ -73,9 +73,11 @@ class ShowSeed extends StatelessWidget { height: 40, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, shape: RoundedRectangleBorder( + foregroundColor: Colors.black, + shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), - ), backgroundColor: orangeC, + ), + backgroundColor: orangeC, elevation: 1, // foreground ), onPressed: () { @@ -121,7 +123,8 @@ class ShowSeed extends StatelessWidget { height: 60 * ratio, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.pop(context); diff --git a/lib/screens/myWallets/wallet_options.dart b/lib/screens/myWallets/wallet_options.dart index bdb3799..bcbd873 100644 --- a/lib/screens/myWallets/wallet_options.dart +++ b/lib/screens/myWallets/wallet_options.dart @@ -299,7 +299,8 @@ class WalletOptions extends StatelessWidget { child: ElevatedButton( key: keyConfirmIdentity, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { walletProvider.confirmIdentityPopup(context); @@ -363,9 +364,11 @@ class WalletOptions extends StatelessWidget { height: 40, child: ElevatedButton( style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, shape: RoundedRectangleBorder( + foregroundColor: Colors.black, + shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), - ), backgroundColor: orangeC, + ), + backgroundColor: orangeC, elevation: 1, // foreground ), onPressed: () { diff --git a/lib/screens/myWallets/wallets_home.dart b/lib/screens/myWallets/wallets_home.dart index ef355d2..2cb0d0a 100644 --- a/lib/screens/myWallets/wallets_home.dart +++ b/lib/screens/myWallets/wallets_home.dart @@ -36,7 +36,6 @@ class WalletsHome extends StatelessWidget { myWalletProvider.listWallets = myWalletProvider.readAllWallets(currentChestNumber); - return WillPopScope( onWillPop: () { // myWalletProvider.pinCode = myWalletProvider.mnemonic = ''; @@ -88,7 +87,8 @@ class WalletsHome extends StatelessWidget { height: 60, ), style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 2, backgroundColor: floattingYellow, // foreground + foregroundColor: Colors.black, elevation: 2, + backgroundColor: floattingYellow, // foreground ), onPressed: () => Navigator.push( context, diff --git a/lib/screens/onBoarding/5.dart b/lib/screens/onBoarding/5.dart index f82c2e9..5609e67 100644 --- a/lib/screens/onBoarding/5.dart +++ b/lib/screens/onBoarding/5.dart @@ -83,7 +83,8 @@ class _ChooseChestState extends State { child: ElevatedButton( key: keyGenerateMnemonic, style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 4, backgroundColor: const Color(0xffFFD58D), // foreground + foregroundColor: Colors.black, elevation: 4, + backgroundColor: const Color(0xffFFD58D), // foreground ), onPressed: () { // _generateWalletProvider.reloadBuild(); @@ -231,7 +232,8 @@ Widget nextButton( child: ElevatedButton( key: keyGoNext, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { generateWalletProvider.nbrWord = generateWalletProvider.getRandomInt(); diff --git a/lib/screens/onBoarding/9.dart b/lib/screens/onBoarding/9.dart index 6958157..7b54b60 100644 --- a/lib/screens/onBoarding/9.dart +++ b/lib/screens/onBoarding/9.dart @@ -81,7 +81,10 @@ class OnboardingStepNine extends StatelessWidget { child: ElevatedButton( key: keyChangePin, style: ElevatedButton.styleFrom( - foregroundColor: Colors.black, elevation: 4, backgroundColor: const Color(0xffFFD58D), // foreground + foregroundColor: Colors.black, + elevation: 4, + backgroundColor: + const Color(0xffFFD58D), // foreground ), onPressed: () { generateWalletProvider.changePinCode( diff --git a/lib/screens/search.dart b/lib/screens/search.dart index a28a7dc..ece009b 100644 --- a/lib/screens/search.dart +++ b/lib/screens/search.dart @@ -95,7 +95,8 @@ class SearchScreen extends StatelessWidget { child: ElevatedButton( key: keyConfirmSearch, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: searchProvider.searchController.text.length >= 2 ? () { diff --git a/lib/screens/transaction_in_progress.dart b/lib/screens/transaction_in_progress.dart index 6bd77e4..88d10e2 100644 --- a/lib/screens/transaction_in_progress.dart +++ b/lib/screens/transaction_in_progress.dart @@ -267,7 +267,8 @@ class TransactionInProgress extends StatelessWidget { child: ElevatedButton( key: keyCloseTransactionScreen, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: () { Navigator.pop(context); diff --git a/lib/screens/wallet_view.dart b/lib/screens/wallet_view.dart index 27f971b..172bade 100644 --- a/lib/screens/wallet_view.dart +++ b/lib/screens/wallet_view.dart @@ -626,7 +626,8 @@ class WalletViewScreen extends StatelessWidget { child: ElevatedButton( key: keyConfirmPayment, style: ElevatedButton.styleFrom( - foregroundColor: Colors.white, elevation: 4, backgroundColor: orangeC, // foreground + foregroundColor: Colors.white, elevation: 4, + backgroundColor: orangeC, // foreground ), onPressed: canValidate ? () async { From 0fe0c4d3c5e92b13b7003f8012c3dabfb4410801 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 5 Sep 2022 08:35:24 +0200 Subject: [PATCH 27/28] remove unused deps --- lib/globals.dart | 2 +- lib/screens/settings.dart | 1 - pubspec.lock | 232 ++++++-------------------------------- pubspec.yaml | 23 +--- 4 files changed, 34 insertions(+), 224 deletions(-) diff --git a/lib/globals.dart b/lib/globals.dart index dff45e6..eb199e7 100644 --- a/lib/globals.dart +++ b/lib/globals.dart @@ -3,7 +3,7 @@ import 'package:flutter/material.dart'; import 'package:gecko/models/chest_data.dart'; import 'package:gecko/models/g1_wallets_list.dart'; import 'package:gecko/models/wallet_data.dart'; -import 'package:hive/hive.dart'; +import 'package:hive_flutter/hive_flutter.dart'; import 'package:logger/logger.dart'; import 'package:shared_preferences/shared_preferences.dart'; diff --git a/lib/screens/settings.dart b/lib/screens/settings.dart index 94fee97..e4931c0 100644 --- a/lib/screens/settings.dart +++ b/lib/screens/settings.dart @@ -9,7 +9,6 @@ import 'package:gecko/providers/substrate_sdk.dart'; import 'package:gecko/globals.dart'; import 'package:polkawallet_sdk/api/types/networkParams.dart'; import 'package:provider/provider.dart'; -// import 'package:dropdown_button2/dropdown_button2.dart'; class SettingsScreen extends StatelessWidget { final MyWalletsProvider _myWallets = MyWalletsProvider(); diff --git a/pubspec.lock b/pubspec.lock index 661ba8a..2ace6ec 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,14 +7,14 @@ packages: name: _fe_analyzer_shared url: "https://pub.dartlang.org" source: hosted - version: "44.0.0" + version: "47.0.0" analyzer: dependency: transitive description: name: analyzer url: "https://pub.dartlang.org" source: hosted - version: "4.4.0" + version: "4.7.0" archive: dependency: transitive description: @@ -29,13 +29,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.3.1" - assorted_layout_widgets: - dependency: "direct main" - description: - name: assorted_layout_widgets - url: "https://pub.dartlang.org" - source: hosted - version: "6.1.1" async: dependency: transitive description: @@ -56,7 +49,7 @@ packages: name: barcode url: "https://pub.dartlang.org" source: hosted - version: "2.2.1" + version: "2.2.3" barcode_scan2: dependency: "direct main" description: @@ -147,7 +140,7 @@ packages: name: built_value url: "https://pub.dartlang.org" source: hosted - version: "8.4.0" + version: "8.4.1" carousel_slider: dependency: "direct main" description: @@ -197,20 +190,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.16.0" - confirm_dialog: - dependency: "direct main" - description: - name: confirm_dialog - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" connectivity_plus: dependency: "direct main" description: name: connectivity_plus url: "https://pub.dartlang.org" source: hosted - version: "2.3.6" + version: "2.3.6+1" connectivity_plus_linux: dependency: transitive description: @@ -253,13 +239,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.2" - coverage: - dependency: transitive - description: - name: coverage - url: "https://pub.dartlang.org" - source: hosted - version: "1.5.0" cross_file: dependency: transitive description: @@ -268,7 +247,7 @@ packages: source: hosted version: "0.3.3+1" crypto: - dependency: "direct main" + dependency: transitive description: name: crypto url: "https://pub.dartlang.org" @@ -287,14 +266,7 @@ packages: name: dbus url: "https://pub.dartlang.org" source: hosted - version: "0.7.7" - desktop_window: - dependency: "direct main" - description: - name: desktop_window - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.0" + version: "0.7.8" dio: dependency: "direct main" description: @@ -309,13 +281,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" - dropdown_button2: - dependency: "direct main" - description: - name: dropdown_button2 - url: "https://pub.dartlang.org" - source: hosted - version: "1.7.1" durt: dependency: "direct main" description: @@ -345,7 +310,7 @@ packages: source: hosted version: "1.3.1" fast_base58: - dependency: "direct main" + dependency: transitive description: name: fast_base58 url: "https://pub.dartlang.org" @@ -422,20 +387,13 @@ packages: description: flutter source: sdk version: "0.0.0" - flutter_logs: - dependency: "direct main" - description: - name: flutter_logs - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.7" flutter_markdown: dependency: "direct main" description: name: flutter_markdown url: "https://pub.dartlang.org" source: hosted - version: "0.6.10+3" + version: "0.6.10+5" flutter_plugin_android_lifecycle: dependency: transitive description: @@ -443,13 +401,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.7" - flutter_svg: - dependency: "direct main" - description: - name: flutter_svg - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" flutter_test: dependency: "direct dev" description: flutter @@ -571,7 +522,7 @@ packages: source: hosted version: "0.2.0" hive: - dependency: "direct main" + dependency: transitive description: name: hive url: "https://pub.dartlang.org" @@ -584,15 +535,8 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" - hive_generator: - dependency: "direct dev" - description: - name: hive_generator - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.3" http: - dependency: "direct main" + dependency: transitive description: name: http url: "https://pub.dartlang.org" @@ -625,7 +569,7 @@ packages: name: icons_launcher url: "https://pub.dartlang.org" source: hosted - version: "2.0.2" + version: "2.0.5" image: dependency: transitive description: @@ -639,21 +583,21 @@ packages: name: image_cropper url: "https://pub.dartlang.org" source: hosted - version: "2.0.3" + version: "3.0.0" image_cropper_for_web: dependency: transitive description: name: image_cropper_for_web url: "https://pub.dartlang.org" source: hosted - version: "0.0.4" + version: "1.0.2" image_cropper_platform_interface: dependency: transitive description: name: image_cropper_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "3.0.2" image_picker: dependency: "direct main" description: @@ -681,7 +625,7 @@ packages: name: image_picker_ios url: "https://pub.dartlang.org" source: hosted - version: "0.8.5+6" + version: "0.8.6" image_picker_platform_interface: dependency: transitive description: @@ -689,20 +633,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.6.1" - infinite_scroll_pagination: - dependency: "direct main" - description: - name: infinite_scroll_pagination - url: "https://pub.dartlang.org" - source: hosted - version: "3.2.0" integration_test: dependency: "direct dev" description: flutter source: sdk version: "0.0.0" intl: - dependency: "direct main" + dependency: transitive description: name: intl url: "https://pub.dartlang.org" @@ -799,13 +736,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.5" - matrix4_transform: - dependency: transitive - description: - name: matrix4_transform - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" meta: dependency: transitive description: @@ -841,13 +771,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.5.0" - node_preamble: - dependency: transitive - description: - name: node_preamble - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.1" normalize: dependency: transitive description: @@ -868,7 +791,7 @@ packages: name: package_info_plus url: "https://pub.dartlang.org" source: hosted - version: "1.4.3" + version: "1.4.3+1" package_info_plus_linux: dependency: transitive description: @@ -911,13 +834,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.2" - path_drawing: - dependency: transitive - description: - name: path_drawing - url: "https://pub.dartlang.org" - source: hosted - version: "1.0.1" path_parsing: dependency: transitive description: @@ -938,7 +854,7 @@ packages: name: path_provider_android url: "https://pub.dartlang.org" source: hosted - version: "2.0.17" + version: "2.0.20" path_provider_ios: dependency: transitive description: @@ -973,7 +889,7 @@ packages: name: path_provider_windows url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.3" path_tree: dependency: transitive description: @@ -987,7 +903,7 @@ packages: name: pdf url: "https://pub.dartlang.org" source: hosted - version: "3.8.2" + version: "3.8.3" permission_handler: dependency: "direct main" description: @@ -1122,14 +1038,7 @@ packages: name: pubspec_parse url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" - pull_to_refresh: - dependency: "direct main" - description: - name: pull_to_refresh - url: "https://pub.dartlang.org" - source: hosted - version: "2.0.0" + version: "1.2.1" qr: dependency: transitive description: @@ -1146,13 +1055,6 @@ packages: url: "https://github.com/insinfo/qr.flutter.git" source: git version: "4.0.0" - responsive_builder: - dependency: "direct main" - description: - name: responsive_builder - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.2" responsive_framework: dependency: "direct main" description: @@ -1168,19 +1070,19 @@ packages: source: hosted version: "0.27.5" sentry: - dependency: "direct main" + dependency: transitive description: name: sentry url: "https://pub.dartlang.org" source: hosted - version: "6.9.0" + version: "6.9.1" sentry_flutter: dependency: "direct main" description: name: sentry_flutter url: "https://pub.dartlang.org" source: hosted - version: "6.9.0" + version: "6.9.1" shared_preferences: dependency: "direct main" description: @@ -1222,7 +1124,7 @@ packages: name: shared_preferences_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "2.0.0" + version: "2.1.0" shared_preferences_web: dependency: transitive description: @@ -1244,20 +1146,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.2" - shelf_packages_handler: - dependency: transitive - description: - name: shelf_packages_handler - url: "https://pub.dartlang.org" - source: hosted - version: "3.0.1" - shelf_static: - dependency: transitive - description: - name: shelf_static - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.1" shelf_web_socket: dependency: transitive description: @@ -1270,41 +1158,6 @@ packages: description: flutter source: sdk version: "0.0.99" - sliver_tools: - dependency: transitive - description: - name: sliver_tools - url: "https://pub.dartlang.org" - source: hosted - version: "0.2.7" - source_gen: - dependency: transitive - description: - name: source_gen - url: "https://pub.dartlang.org" - source: hosted - version: "1.2.2" - source_helper: - dependency: transitive - description: - name: source_helper - url: "https://pub.dartlang.org" - source: hosted - version: "1.3.2" - source_map_stack_trace: - dependency: transitive - description: - name: source_map_stack_trace - url: "https://pub.dartlang.org" - source: hosted - version: "2.1.0" - source_maps: - dependency: transitive - description: - name: source_maps - url: "https://pub.dartlang.org" - source: hosted - version: "0.10.10" source_span: dependency: transitive description: @@ -1341,7 +1194,7 @@ packages: source: hosted version: "1.1.1" sync_http: - dependency: "direct main" + dependency: transitive description: name: sync_http url: "https://pub.dartlang.org" @@ -1354,13 +1207,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.1" - test: - dependency: "direct main" - description: - name: test - url: "https://pub.dartlang.org" - source: hosted - version: "1.21.4" test_api: dependency: transitive description: @@ -1368,13 +1214,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.4.12" - test_core: - dependency: transitive - description: - name: test_core - url: "https://pub.dartlang.org" - source: hosted - version: "0.4.16" timing: dependency: transitive description: @@ -1439,7 +1278,7 @@ packages: source: hosted version: "1.0.1" web_socket_channel: - dependency: "direct main" + dependency: transitive description: name: web_socket_channel url: "https://pub.dartlang.org" @@ -1452,13 +1291,6 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.0.0" - webkit_inspection_protocol: - dependency: transitive - description: - name: webkit_inspection_protocol - url: "https://pub.dartlang.org" - source: hosted - version: "1.1.0" webview_flutter: dependency: transitive description: @@ -1472,14 +1304,14 @@ packages: name: webview_flutter_android url: "https://pub.dartlang.org" source: hosted - version: "2.9.3" + version: "2.10.0" webview_flutter_platform_interface: dependency: transitive description: name: webview_flutter_platform_interface url: "https://pub.dartlang.org" source: hosted - version: "1.9.1" + version: "1.9.3" webview_flutter_wkwebview: dependency: transitive description: @@ -1500,9 +1332,9 @@ packages: name: xdg_directories url: "https://pub.dartlang.org" source: hosted - version: "0.2.0+1" + version: "0.2.0+2" xml: - dependency: "direct main" + dependency: transitive description: name: xml url: "https://pub.dartlang.org" diff --git a/pubspec.yaml b/pubspec.yaml index bdd79c1..6797c1a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,23 +15,12 @@ dependencies: sdk: flutter flutter_driver: sdk: flutter - assorted_layout_widgets: ^6.1.1 bubble: ^1.2.1 carousel_slider: ^4.0.0 - confirm_dialog: ^1.0.0 - crypto: ^3.0.1 - fast_base58: ^0.2.0 flutter_lints: ^2.0.1 - flutter_logs: ^2.1.4 - flutter_svg: ^1.1.3 graphql_flutter: ^5.1.1-beta.3 - hive: ^2.0.4 hive_flutter: ^1.1.0 - http: ^0.13.4 - # image_gallery_saver: ^1.6.9 image_picker: ^0.8.4 - infinite_scroll_pagination: ^3.1.0 - intl: ^0.17.0 jdenticon_dart: ^2.0.0 logger: ^1.1.0 path_provider: ^2.0.9 @@ -45,19 +34,12 @@ dependencies: git: url: https://github.com/insinfo/qr.flutter.git ref: master - responsive_builder: ^0.4.1 responsive_framework: ^0.2.0 - sentry: ^6.5.1 sentry_flutter: ^6.5.1 shared_preferences: ^2.0.7 - sync_http: ^0.3.0 - test: ^1.17.10 truncate: ^3.0.1 unorm_dart: ^0.2.0 - xml: ^6.1.0 - pull_to_refresh: ^2.0.0 dio: ^4.0.4 - desktop_window: ^0.4.0 durt: ^0.1.6 package_info_plus: ^1.4.2 polkawallet_sdk: #^0.4.9 @@ -68,12 +50,10 @@ dependencies: # ref: gecko-old ref: gecko-unwrapbytes dots_indicator: ^2.1.0 - web_socket_channel: ^2.2.0 connectivity_plus: ^2.3.3 - image_cropper: ^2.0.3 + image_cropper: ^3.0.0 easy_localization: ^3.0.1 flutter_markdown: ^0.6.10+2 - dropdown_button2: ^1.6.3 pointycastle: ^3.6.1 hex: ^0.2.0 flutter_dotenv: ^5.0.2 @@ -85,7 +65,6 @@ dev_dependencies: build_runner: ^2.1.2 flutter_test: sdk: flutter - hive_generator: ^1.1.1 integration_test: sdk: flutter From 34c69b64eee9263abc5de9d70754903b705d95a8 Mon Sep 17 00:00:00 2001 From: poka Date: Mon, 5 Sep 2022 09:42:44 +0200 Subject: [PATCH 28/28] bump CI v0.0.11 --- .gitlab-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 20e7767..865439e 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -5,7 +5,7 @@ stages: - package .env: - image: axiomteam/gecko-ci:v0.0.9 + image: axiomteam/gecko-ci:v0.0.11 tags: - redshift