import 'dart:io'; import 'package:hash_wallet/entities/seed_type.dart'; import 'package:hash_wallet/reactions/wallet_utils.dart'; import 'package:hash_wallet/wallet_types.g.dart'; import 'package:cw_core/currency_for_wallet_type.dart'; import 'package:cw_core/wallet_type.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; import 'package:hash_wallet/main.dart' as app; import '../robots/create_pin_welcome_page_robot.dart'; import '../robots/new_wallet_page_robot.dart'; import '../robots/new_wallet_type_page_robot.dart'; import '../robots/pre_seed_page_robot.dart'; import '../robots/restore_from_seed_or_key_robot.dart'; import '../robots/restore_options_page_robot.dart'; import '../robots/seed_verification_page_robot.dart'; import '../robots/setup_pin_code_robot.dart'; import '../robots/wallet_group_description_page_robot.dart'; import '../robots/wallet_list_page_robot.dart'; import '../robots/wallet_seed_page_robot.dart'; import '../robots/welcome_page_robot.dart'; import 'common_test_cases.dart'; import 'package:hash_wallet/.secrets.g.dart' as secrets; import 'common_test_constants.dart'; class CommonTestFlows { CommonTestFlows(this._tester) : _commonTestCases = CommonTestCases(_tester), _welcomePageRobot = WelcomePageRobot(_tester), _preSeedPageRobot = PreSeedPageRobot(_tester), _setupPinCodeRobot = SetupPinCodeRobot(_tester), _newWalletPageRobot = NewWalletPageRobot(_tester), _walletSeedPageRobot = WalletSeedPageRobot(_tester), _walletListPageRobot = WalletListPageRobot(_tester), _newWalletTypePageRobot = NewWalletTypePageRobot(_tester), _restoreOptionsPageRobot = RestoreOptionsPageRobot(_tester), _seedVerificationPageRobot = SeedVerificationPageRobot(_tester), _createPinWelcomePageRobot = CreatePinWelcomePageRobot(_tester), _restoreFromSeedOrKeysPageRobot = RestoreFromSeedOrKeysPageRobot(_tester), _walletGroupDescriptionPageRobot = WalletGroupDescriptionPageRobot(_tester); final WidgetTester _tester; final CommonTestCases _commonTestCases; final WelcomePageRobot _welcomePageRobot; final PreSeedPageRobot _preSeedPageRobot; final SetupPinCodeRobot _setupPinCodeRobot; final NewWalletPageRobot _newWalletPageRobot; final WalletSeedPageRobot _walletSeedPageRobot; final WalletListPageRobot _walletListPageRobot; final NewWalletTypePageRobot _newWalletTypePageRobot; final RestoreOptionsPageRobot _restoreOptionsPageRobot; final CreatePinWelcomePageRobot _createPinWelcomePageRobot; final SeedVerificationPageRobot _seedVerificationPageRobot; final RestoreFromSeedOrKeysPageRobot _restoreFromSeedOrKeysPageRobot; final WalletGroupDescriptionPageRobot _walletGroupDescriptionPageRobot; //* ========== Handles flow to start the app afresh and accept disclaimer ============= Future startAppFlow(Key key) async { await app.main(topLevelKey: key); await _tester.pump(Duration(seconds: 2)); // // --------- Disclaimer Page ------------ // // Tap checkbox to accept disclaimer // await _disclaimerPageRobot.tapDisclaimerCheckbox(); // // Tap accept button // await _disclaimerPageRobot.tapAcceptButton(); } //* ========== Handles flow from welcome to creating a new wallet =============== Future welcomePageToCreateNewWalletFlow( WalletType walletTypeToCreate, List walletPin, ) async { await _welcomeToCreateWalletPath(walletTypeToCreate, walletPin); await _generateNewWalletDetails(); await _confirmPreSeedInfo(); await _confirmWalletDetails(); await _verifyWalletSeed(); } //* ========== Handles flow from welcome to restoring wallet from seeds =============== Future welcomePageToRestoreWalletThroughSeedsFlow( WalletType walletTypeToRestore, String walletSeed, List walletPin, ) async { await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin); await _restoreFromSeeds(walletTypeToRestore, walletSeed); } //* ========== Handles flow from welcome to restoring wallet from keys =============== Future welcomePageToRestoreWalletThroughKeysFlow( WalletType walletTypeToRestore, List walletPin, ) async { await _welcomeToRestoreFromSeedsOrKeysPath(walletTypeToRestore, walletPin); await _restoreFromKeys(); } void confirmAllAvailableWalletTypeIconsDisplayCorrectly() { for (var walletType in availableWalletTypes) { final imageUrl = walletTypeToCryptoCurrency(walletType).iconPath; final walletIconFinder = find.image( Image.asset( imageUrl!, width: 32, height: 32, ).image, ); expect(walletIconFinder, findsAny); } } //* ========== Handles creating new wallet flow from wallet list/menu =============== Future createNewWalletFromWalletMenu(WalletType walletTypeToCreate) async { _tester.printToConsole('Creating ${walletTypeToCreate.name} Wallet'); await _tester.pumpAndSettle(Duration(milliseconds: 1000)); await _walletListPageRobot.navigateToCreateNewWalletPage(); await _commonTestCases.defaultSleepTime(); await _selectWalletTypeForWallet(walletTypeToCreate); await _commonTestCases.defaultSleepTime(); // ---- Wallet Group/New Seed Implementation Comes here await _walletGroupDescriptionPageFlow(true, walletTypeToCreate); await _generateNewWalletDetails(); await _confirmPreSeedInfo(); await _confirmWalletDetails(); await _verifyWalletSeed(); await _commonTestCases.defaultSleepTime(); } Future _walletGroupDescriptionPageFlow(bool isNewSeed, WalletType walletType) async { if (!isBIP39Wallet(walletType)) return; await _walletGroupDescriptionPageRobot.isWalletGroupDescriptionPage(); if (isNewSeed) { await _walletGroupDescriptionPageRobot.navigateToCreateNewSeedPage(); } else { await _walletGroupDescriptionPageRobot.navigateToChooseWalletGroup(); } } //* ========== Handles restore wallet flow from wallet list/menu =============== Future restoreWalletFromWalletMenu(WalletType walletType, String walletSeed) async { _tester.printToConsole('Restoring ${walletType.name} Wallet'); await _walletListPageRobot.navigateToRestoreWalletOptionsPage(); await _commonTestCases.defaultSleepTime(); if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage(); if (!Platform.isLinux) await _commonTestCases.defaultSleepTime(); await _selectWalletTypeForWallet(walletType); await _commonTestCases.defaultSleepTime(); await _restoreFromSeeds(walletType, walletSeed); await _commonTestCases.defaultSleepTime(); } //* ========== Handles setting up pin code for wallet on first install =============== Future setupPinCodeForWallet(List pin) async { if (Platform.isLinux) return; // ----------- SetupPinCode Page ------------- // Confirm initial defaults - Widgets to be displayed etc await _setupPinCodeRobot.isSetupPinCodePage(); await _setupPinCodeRobot.enterPinCode(pin); await _setupPinCodeRobot.enterPinCode(pin); await _setupPinCodeRobot.tapSuccessButton(); } Future _welcomeToCreateWalletPath( WalletType walletTypeToCreate, List pin, ) async { await _createPinWelcomePageRobot.tapSetAPinButton(); await setupPinCodeForWallet(pin); await _welcomePageRobot.navigateToCreateNewWalletPage(); await _selectWalletTypeForWallet(walletTypeToCreate); if (_welcomePageRobot.hasNewSingleSeedButton()) { await _welcomePageRobot.tapNewSingleSeed(); } } Future _welcomeToRestoreFromSeedsOrKeysPath( WalletType walletTypeToRestore, List pin, ) async { await _createPinWelcomePageRobot.tapSetAPinButton(); await setupPinCodeForWallet(pin); await _welcomePageRobot.navigateToRestoreWalletPage(); if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage(); await _selectWalletTypeForWallet(walletTypeToRestore); } //* ============ Handles New Wallet Type Page ================== Future _selectWalletTypeForWallet(WalletType type) async { // ----------- NewWalletType Page ------------- _tester.printToConsole('Selecting wallet type: ${type.name}'); await _tester.pumpAndSettle(Duration(milliseconds: 1000)); await _newWalletTypePageRobot.findParticularWalletTypeInScrollableList(type); _tester.printToConsole('Tapping wallet type: ${type.name}'); await _newWalletTypePageRobot.selectWalletType(type); await _tester.pumpAndSettle(Duration(milliseconds: 500)); _tester.printToConsole('Pressing next button'); await _newWalletTypePageRobot.onNextButtonPressed(); await _tester.pumpAndSettle(Duration(milliseconds: 2000)); _tester.printToConsole('Wallet type selection completed for: ${type.name}'); } //* ============ Handles New Wallet Page ================== Future _generateNewWalletDetails() async { _tester.printToConsole('Attempting to find NewWalletPage...'); await _tester.pumpAndSettle(Duration(milliseconds: 1000)); await _newWalletPageRobot.isNewWalletPage(); _tester.printToConsole('NewWalletPage found successfully'); await _newWalletPageRobot.generateWalletName(); if (Platform.isLinux) { // manual pin input await _restoreFromSeedOrKeysPageRobot .enterPasswordForWalletRestore(CommonTestConstants.pin.join("")); await _restoreFromSeedOrKeysPageRobot .enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join("")); } await _newWalletPageRobot.onNextButtonPressed(); } //* ============ Handles Pre Seed Page ===================== Future _confirmPreSeedInfo() async { await _preSeedPageRobot.isPreSeedPage(); await _preSeedPageRobot.onConfirmButtonPressed(); } //* ============ Handles Wallet Seed Page ================== Future _confirmWalletDetails() async { await _walletSeedPageRobot.isWalletSeedPage(); _walletSeedPageRobot.confirmWalletDetailsDisplayCorrectly(); _walletSeedPageRobot.confirmWalletSeedReminderDisplays(); // await _walletSeedPageRobot.onCopySeedsButtonPressed(); await _walletSeedPageRobot.onVerifySeedButtonPressed(); } //* ============ Handles Wallet Seed Verification Page ================== Future _verifyWalletSeed() async { await _seedVerificationPageRobot.isSeedVerificationPage(); _seedVerificationPageRobot.hasTitle(); await _seedVerificationPageRobot.verifyWalletSeeds(); } //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action Future _restoreFromSeeds(WalletType type, String walletSeed) async { // ----------- RestoreFromSeedOrKeys Page ------------- await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions(); await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore(walletSeed); final numberOfWords = walletSeed.split(' ').length; if (numberOfWords == 25 && (type == WalletType.monero)) { await _restoreFromSeedOrKeysPageRobot .chooseSeedTypeForMoneroOrWowneroWallets(MoneroSeedType.legacy); // Using a constant value of 2831400 for the blockheight as its the restore blockheight for our testing wallet await _restoreFromSeedOrKeysPageRobot .enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight); } if (Platform.isLinux) { // manual pin input await _restoreFromSeedOrKeysPageRobot .enterPasswordForWalletRestore(CommonTestConstants.pin.join("")); await _restoreFromSeedOrKeysPageRobot .enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join("")); } await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed(); } //* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Keys Action Future _restoreFromKeys() async { await _commonTestCases.swipePage(); await _commonTestCases.defaultSleepTime(); await _restoreFromSeedOrKeysPageRobot.selectWalletNameFromAvailableOptions( isSeedFormEntry: false, ); await _restoreFromSeedOrKeysPageRobot.enterSeedPhraseForWalletRestore(''); await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed(); } //* ====== Utility Function to get test wallet seeds for each wallet type ======== String getWalletSeedsByWalletType(WalletType walletType) { switch (walletType) { case WalletType.monero: return secrets.moneroTestWalletSeeds; case WalletType.bitcoin: return secrets.bitcoinTestWalletSeeds; case WalletType.ethereum: return secrets.ethereumTestWalletSeeds; case WalletType.litecoin: return secrets.litecoinTestWalletSeeds; case WalletType.bitcoinCash: return secrets.bitcoinCashTestWalletSeeds; case WalletType.polygon: return secrets.polygonTestWalletSeeds; case WalletType.base: return secrets.baseTestWalletSeeds; case WalletType.arbitrum: return secrets.arbitrumTestWalletSeeds; case WalletType.bsc: return secrets.bscTestWalletSeeds; case WalletType.nano: return secrets.nanoTestWalletSeeds; case WalletType.wownero: return secrets.wowneroTestWalletSeeds; // Hash Bags does not ship SOL/TRX/ZEC/DCR/ZANO/Haven — those WalletType // members no longer exist. dogecoin ships, but has no test seed in // .secrets.g.dart. case WalletType.dogecoin: case WalletType.none: case WalletType.banano: throw Exception("Unable to get seeds for ${walletType}"); } } //* ====== Utility Function to get test receive address for each wallet type ======== String getReceiveAddressByWalletType(WalletType walletType) { switch (walletType) { case WalletType.monero: return secrets.moneroTestWalletReceiveAddress; case WalletType.bitcoin: return secrets.bitcoinTestWalletReceiveAddress; case WalletType.ethereum: return secrets.ethereumTestWalletReceiveAddress; case WalletType.litecoin: return secrets.litecoinTestWalletReceiveAddress; case WalletType.bitcoinCash: return secrets.bitcoinCashTestWalletReceiveAddress; case WalletType.polygon: return secrets.polygonTestWalletReceiveAddress; case WalletType.base: return secrets.baseTestWalletReceiveAddress; case WalletType.arbitrum: return secrets.arbitrumTestWalletReceiveAddress; case WalletType.bsc: return secrets.bscTestWalletReceiveAddress; case WalletType.nano: return secrets.nanoTestWalletReceiveAddress; case WalletType.wownero: return secrets.wowneroTestWalletReceiveAddress; default: return ''; } } }