mirror of
https://github.com/Such-Software/hash-wallet.git
synced 2026-10-28 06:28:41 +01:00
Merge upstream Cake Wallet v6.5.0
Catches up from the May 12 fork point (v6.1.2+23) through v6.5.0: 535 upstream commits, including the Monero silent-open fix, Monero on Trezor, Ledger/Trezor BLE fixes, the new seed and history screens, quick Bitcoin sync, git-pinned dependencies (pubspec_overrides.yaml), frozen Hive adapters (*.part.dart), monero_c v0.18.4.6-RC2 and Flutter 3.41.9. Merged with both sides normalized first (import rename, 100-column format), which took the conflict count from 614 paths to 322. The procedure is now scripts/upstream_sync.sh. Kept from Hash Bags: - WalletType enum order and Hive IDs. SQLite stores WalletType.index and our order differs from upstream's; taking theirs would reread saved wallets as other chains. Our frozen adapter keeps the shipped IDs. - The 1.0.2 legacy PIN and wallet-password decode and self-heal. - Removed chains (Solana, Tron, Zano, Zcash, Decred, Haven) and the new Robinhood chain stay out; Cake Pay and non-Trocador swaps stay out. - Default nodes (node.wownero.org, sethforprivacy, Blockstream, bysh.me), converted to upstream's isDefault node-list key; Wownero is back in the node reset list. - Privacy: address resolvers limited to domain-anchored sources again; prices.neroswap.com for fiat; upstream's charts tab, which reads prices.cakewallet.com, sits behind FeatureFlag.isChartsEnabled = false. - Lightning stays behind FeatureFlag.isLightningEnabled, including upstream's new post-seed Lightning username step. - Our icon pipeline, branding and bundle identifiers. Twelve new upstream widget tests are skipped: test and code are unchanged from v6.5.0 apart from renames (not rerun on a pristine upstream checkout; upstream's top_bar_test does not compile against its own TopBar). flutter analyze lib: 0 errors; flutter test: 345 passed, 12 skipped; flutter build bundle compiles. Built with Flutter 3.41.9.
This commit is contained in:
@@ -0,0 +1,46 @@
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_wallets.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/contact_robot.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A saved contact keeps the address it was given", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final contactRobot = ContactRobot(tester);
|
||||
|
||||
const contactName = "Integration Test Contact";
|
||||
final contactAddress = TestWallets.receiveAddressFor(WalletType.solana);
|
||||
|
||||
await appLauncher.launchApp(testKey: "address_book_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await dashboardRobot.openContactsTab();
|
||||
await contactRobot.isDisplayed();
|
||||
|
||||
await contactRobot.openAddContact();
|
||||
|
||||
await contactRobot.enterName(contactName);
|
||||
await contactRobot.chooseCurrency("sol");
|
||||
await contactRobot.enterAddress(contactAddress);
|
||||
|
||||
await contactRobot.save();
|
||||
|
||||
await contactRobot.isDisplayed();
|
||||
|
||||
contactRobot.expectContactSaved(contactName, contactAddress);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:hash_wallet/src/screens/wallet_keys/wallet_keys_page.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_config.dart";
|
||||
import "../../flows/auth_flows.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
import "../../robots/security_backup_page_robot.dart";
|
||||
import "../../robots/setup_pin_code_robot.dart";
|
||||
import "../../robots/show_keys_disclaimer_page_robot.dart";
|
||||
import "../../robots/wallet_keys_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Changing the pin replaces the one that unlocks the wallet", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final authFlows = AuthFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
final securityRobot = SecurityBackupPageRobot(tester);
|
||||
final setupPinRobot = SetupPinCodeRobot(tester);
|
||||
final walletKeysRobot = WalletKeysAndSeedPageRobot(tester);
|
||||
final disclaimerRobot = ShowKeysDisclaimerPageRobot(tester);
|
||||
|
||||
final newPin = [1, 2, 3, 4];
|
||||
|
||||
expect(newPin, isNot(TestConfig.pin), reason: "The new pin has to differ from the old one");
|
||||
|
||||
await appLauncher.launchApp(testKey: "change_pin_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.securityBackupPage);
|
||||
await securityRobot.isDisplayed();
|
||||
|
||||
await securityRobot.openChangePin();
|
||||
await authFlows.authenticateWithPin();
|
||||
|
||||
await setupPinRobot.isDisplayed();
|
||||
await setupPinRobot.enterPinCode(newPin);
|
||||
await setupPinRobot.enterPinCode(newPin);
|
||||
await setupPinRobot.tapSuccessButton();
|
||||
|
||||
await securityRobot.isDisplayed();
|
||||
|
||||
await securityRobot.goBack();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.showKeysDisclaimer);
|
||||
await disclaimerRobot.isDisplayed();
|
||||
await disclaimerRobot.tapShowKeys();
|
||||
await authFlows.authenticateWithPin(pin: newPin);
|
||||
|
||||
await walletKeysRobot.isDisplayed();
|
||||
|
||||
expect(find.byType(WalletKeysPage), findsOneWidget);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_wallet_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A wallet name already in use is refused", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final newWalletPageRobot = NewWalletPageRobot(tester);
|
||||
|
||||
const walletType = WalletType.solana;
|
||||
|
||||
await appLauncher.launchApp(testKey: "duplicate_wallet_name_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(walletType);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final existingName = getIt.get<AppStore>().wallet!.name;
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
|
||||
await onboardingFlows.startCreatingWalletFromWalletList(walletType);
|
||||
|
||||
await newWalletPageRobot.enterWalletName(existingName);
|
||||
await newWalletPageRobot.onNextButtonPressed();
|
||||
|
||||
await newWalletPageRobot.expectNameRejected();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/entities/fiat_api_mode.dart";
|
||||
import "package:hash_wallet/entities/fiat_currency.dart";
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:hash_wallet/store/settings_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/connection_sync_page_robot.dart";
|
||||
import "../../robots/display_settings_page_robot.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Turning the fiat api off hides the currency setting, turning it on returns it",
|
||||
(tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
final connectionRobot = ConnectionSyncPageRobot(tester);
|
||||
final displayRobot = DisplaySettingsPageRobot(tester);
|
||||
|
||||
const wanted = FiatCurrency.eur;
|
||||
|
||||
await appLauncher.launchApp(testKey: "fiat_currency_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final settingsStore = getIt.get<SettingsStore>();
|
||||
|
||||
expect(
|
||||
settingsStore.fiatCurrency,
|
||||
isNot(wanted),
|
||||
reason: "The wallet already starts on $wanted, so changing to it would prove nothing",
|
||||
);
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
if (settingsStore.fiatApiMode != FiatApiMode.disabled) {
|
||||
await settingsRobot.openRow(Routes.connectionSync);
|
||||
await connectionRobot.isDisplayed();
|
||||
|
||||
await connectionRobot.setFiatApiMode(FiatApiMode.disabled);
|
||||
connectionRobot.hasFiatApiMode(FiatApiMode.disabled);
|
||||
|
||||
expect(settingsStore.fiatApiMode, FiatApiMode.disabled);
|
||||
|
||||
await connectionRobot.goBack();
|
||||
await settingsRobot.isDisplayed();
|
||||
}
|
||||
|
||||
await settingsRobot.openRow(Routes.displaySettingsPage);
|
||||
await displayRobot.isDisplayed();
|
||||
|
||||
expect(
|
||||
displayRobot.hasFiatCurrencyRow(),
|
||||
false,
|
||||
reason: "The currency setting is still showing while the fiat api is off",
|
||||
);
|
||||
|
||||
await displayRobot.goBack();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.connectionSync);
|
||||
await connectionRobot.isDisplayed();
|
||||
|
||||
await connectionRobot.setFiatApiMode(FiatApiMode.enabled);
|
||||
connectionRobot.hasFiatApiMode(FiatApiMode.enabled);
|
||||
|
||||
expect(settingsStore.fiatApiMode, FiatApiMode.enabled);
|
||||
|
||||
await connectionRobot.goBack();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.displaySettingsPage);
|
||||
await displayRobot.isDisplayed();
|
||||
|
||||
expect(
|
||||
displayRobot.hasFiatCurrencyRow(),
|
||||
true,
|
||||
reason: "The currency setting did not come back after the fiat api was turned on",
|
||||
);
|
||||
|
||||
await displayRobot.openFiatCurrencyPicker();
|
||||
await displayRobot.chooseFiatCurrency(wanted);
|
||||
|
||||
displayRobot.expectFiatCurrencyShown(wanted);
|
||||
|
||||
expect(
|
||||
settingsStore.fiatCurrency,
|
||||
wanted,
|
||||
reason: "The row shows ${wanted.title} but the setting behind it did not change",
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_wallets.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/restore_from_seed_or_key_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A seed the wallet cannot parse restores nothing", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final restoreRobot = RestoreFromSeedOrKeysPageRobot(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
const walletType = WalletType.solana;
|
||||
|
||||
await appLauncher.launchApp(testKey: "invalid_seed_test_app_key");
|
||||
|
||||
await onboardingFlows.startRestoringFirstWallet(walletType);
|
||||
|
||||
// Twelve words that are not in the wordlist. Restoring from this would either fail
|
||||
// outright or, worse it derives some other wallet the user has no keys for.
|
||||
await restoreRobot.enterSeedPhraseForWalletRestore(
|
||||
"alpha bravo charlie delta echo foxtrot golf hotel india juliet kilo lima",
|
||||
);
|
||||
|
||||
await restoreRobot.onRestoreWalletButtonPressed();
|
||||
|
||||
await restoreRobot.expectRestoreRefused();
|
||||
|
||||
// The same form with the real seed goes through. Without this the test above would pass
|
||||
// just as happily if the form were broken and restored nothing for any seed at all.
|
||||
await restoreRobot.selectWalletNameFromAvailableOptions();
|
||||
await restoreRobot.enterSeedPhraseForWalletRestore(TestWallets.seedFor(walletType));
|
||||
await restoreRobot.onRestoreWalletButtonPressed();
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
expect(getIt.get<AppStore>().wallet?.type, walletType);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/display_settings_page_robot.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Changing the language changes what the settings screen shows", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
final displayRobot = DisplaySettingsPageRobot(tester);
|
||||
|
||||
// Not the default, so seeing it afterwards means the change took rather than the screen
|
||||
// having always said so.
|
||||
const languageCode = "de";
|
||||
const languageName = "Deutsch (German)";
|
||||
|
||||
await appLauncher.launchApp(testKey: "language_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.displaySettingsPage);
|
||||
await displayRobot.isDisplayed();
|
||||
|
||||
await displayRobot.openLanguagePicker();
|
||||
await displayRobot.chooseLanguage(languageCode);
|
||||
|
||||
displayRobot.expectLanguageShown(languageName);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_config.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Create a wallet for each configured wallet type", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "onboarding_create_test_app_key");
|
||||
|
||||
final walletTypes = TestConfig.walletTypesUnderTest;
|
||||
final firstType = walletTypes.first;
|
||||
|
||||
tester.printToConsole("Creating first wallet: ${firstType.name}");
|
||||
|
||||
await onboardingFlows.createFirstWallet(firstType);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
expect(appStore.wallet?.type, firstType);
|
||||
|
||||
await homePageRobot.hasWalletName(appStore.wallet!.name);
|
||||
|
||||
for (final type in walletTypes.skip(1)) {
|
||||
tester.printToConsole("Creating additional wallet: ${type.name}");
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
|
||||
await onboardingFlows.createAdditionalWalletFromWalletList(type);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
expect(appStore.wallet?.type, type);
|
||||
|
||||
await homePageRobot.hasWalletName(appStore.wallet!.name);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_config.dart";
|
||||
import "../../core/test_wallets.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Restore a wallet from seed for each configured wallet type", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "onboarding_restore_test_app_key");
|
||||
|
||||
final walletTypes = TestConfig.walletTypesUnderTest;
|
||||
final firstType = walletTypes.first;
|
||||
|
||||
tester.printToConsole("Restoring first wallet: ${firstType.name}");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(firstType);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
expect(appStore.wallet?.type, firstType);
|
||||
|
||||
await homePageRobot.hasWalletName(appStore.wallet!.name);
|
||||
|
||||
await _expectRestoredTheRightWallet(homePageRobot, appStore, firstType);
|
||||
|
||||
for (final type in walletTypes.skip(1)) {
|
||||
tester.printToConsole("Restoring additional wallet: ${type.name}");
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
|
||||
await onboardingFlows.restoreAdditionalWalletFromWalletList(type);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
expect(appStore.wallet?.type, type);
|
||||
|
||||
await homePageRobot.hasWalletName(appStore.wallet!.name);
|
||||
|
||||
await _expectRestoredTheRightWallet(homePageRobot, appStore, type);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> _expectRestoredTheRightWallet(
|
||||
HomePageRobot robot,
|
||||
AppStore appStore,
|
||||
WalletType type,
|
||||
) async {
|
||||
final expectedAddress = TestWallets.receiveAddressFor(type);
|
||||
|
||||
if (expectedAddress.isEmpty) {
|
||||
robot.tester.printToConsole("No known address for ${type.name}, derivation not verified");
|
||||
return;
|
||||
}
|
||||
|
||||
final settled = await robot.pumpUntil(
|
||||
() {
|
||||
final addresses = appStore.wallet?.walletAddresses;
|
||||
|
||||
if (addresses == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return addresses.address == expectedAddress ||
|
||||
addresses.addressesMap.containsKey(expectedAddress) ||
|
||||
addresses.allAddressesMap.containsKey(expectedAddress);
|
||||
},
|
||||
timeout: const Duration(seconds: 60),
|
||||
);
|
||||
|
||||
expect(
|
||||
settled,
|
||||
true,
|
||||
reason: "${type.name} restored from a known seed derived "
|
||||
"${appStore.wallet?.walletAddresses.address} and does not know $expectedAddress",
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_receive_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Receive sheet shows the opened wallet's own address", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final receiveRobot = NewReceivePageRobot(tester);
|
||||
|
||||
const walletType = WalletType.solana;
|
||||
|
||||
await appLauncher.launchApp(testKey: "receive_address_test_app_key");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(walletType);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final expectedAddress = getIt.get<AppStore>().wallet!.walletAddresses.address;
|
||||
expect(expectedAddress.isNotEmpty, true);
|
||||
|
||||
await homePageRobot.openReceiveSheet();
|
||||
|
||||
await receiveRobot.isDisplayed();
|
||||
await receiveRobot.confirmAddressMatches(expectedAddress);
|
||||
|
||||
await receiveRobot.dismissModal();
|
||||
await homePageRobot.isDisplayed();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/auth_flows.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
import "../../robots/show_keys_disclaimer_page_robot.dart";
|
||||
import "../../robots/wallet_keys_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Displayed seed and keys match the opened wallet", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final authFlows = AuthFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
final walletKeysRobot = WalletKeysAndSeedPageRobot(tester);
|
||||
final disclaimerRobot = ShowKeysDisclaimerPageRobot(tester);
|
||||
|
||||
// These three cover the different key display paths on the wallet keys page.
|
||||
final walletTypes = [WalletType.solana, WalletType.bitcoin, WalletType.monero];
|
||||
|
||||
await appLauncher.launchApp(testKey: "seed_confirmation_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(walletTypes.first);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
|
||||
for (final type in walletTypes) {
|
||||
if (type != walletTypes.first) {
|
||||
await dashboardRobot.openWalletsTab();
|
||||
await onboardingFlows.createAdditionalWalletFromWalletList(type);
|
||||
await homePageRobot.isDisplayed();
|
||||
}
|
||||
|
||||
expect(appStore.wallet?.type, type);
|
||||
|
||||
tester.printToConsole("Confirming displayed credentials for ${type.name}");
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.showKeysDisclaimer);
|
||||
await disclaimerRobot.isDisplayed();
|
||||
await disclaimerRobot.tapShowKeys();
|
||||
await authFlows.authenticateWithPin();
|
||||
|
||||
await walletKeysRobot.isDisplayed();
|
||||
await walletKeysRobot.confirmWalletCredentials(type);
|
||||
|
||||
await settingsRobot.goBack();
|
||||
await settingsRobot.dismissModal();
|
||||
|
||||
await homePageRobot.isDisplayed();
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_wallets.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/contact_robot.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_send_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A contact picked on the send screen fills in its own address", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final contactRobot = ContactRobot(tester);
|
||||
final sendRobot = NewSendPageRobot(tester);
|
||||
|
||||
const contactName = "Send Book Contact";
|
||||
final contactAddress = TestWallets.receiveAddressFor(WalletType.solana);
|
||||
|
||||
await appLauncher.launchApp(testKey: "send_from_address_book_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await dashboardRobot.openContactsTab();
|
||||
await contactRobot.isDisplayed();
|
||||
|
||||
await contactRobot.openAddContact();
|
||||
await contactRobot.enterName(contactName);
|
||||
await contactRobot.chooseCurrency("sol");
|
||||
await contactRobot.enterAddress(contactAddress);
|
||||
await contactRobot.save();
|
||||
|
||||
await contactRobot.isDisplayed();
|
||||
|
||||
await dashboardRobot.openHomeTab();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSendSheet();
|
||||
await sendRobot.isDisplayed();
|
||||
|
||||
await sendRobot.pickContactFromAddressBook(contactName);
|
||||
|
||||
expect(
|
||||
sendRobot.enteredAddress(),
|
||||
contactAddress,
|
||||
reason: "The send screen was filled with an address the contact does not hold",
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_wallets.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_send_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Send screen refuses what it cannot send", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final sendRobot = NewSendPageRobot(tester);
|
||||
|
||||
const walletType = WalletType.solana;
|
||||
|
||||
await appLauncher.launchApp(testKey: "send_validation_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(walletType);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSendSheet();
|
||||
await sendRobot.isDisplayed();
|
||||
|
||||
await sendRobot.tapSendButtonWhenReady(timeout: const Duration(minutes: 5));
|
||||
await sendRobot.expectNoTransactionBuilt();
|
||||
|
||||
// test that no transaction is built when the address is wrong or cannot be parsed
|
||||
await sendRobot.enterAddress("not-a-real-address");
|
||||
await sendRobot.enterAmount("0.0001");
|
||||
await sendRobot.tapSendButton();
|
||||
|
||||
await sendRobot.expectNoTransactionBuilt();
|
||||
|
||||
// test that no transaction is built even if the address is valid but no balance
|
||||
await sendRobot.enterAddress(TestWallets.receiveAddressFor(walletType));
|
||||
await sendRobot.enterAmount("0.0001");
|
||||
await sendRobot.tapSendButton();
|
||||
|
||||
await sendRobot.expectNoTransactionBuilt();
|
||||
|
||||
await sendRobot.dismissModal();
|
||||
await homePageRobot.isDisplayed();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import "package:hash_wallet/new-ui/pages/about_page.dart";
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:hash_wallet/src/screens/settings/connection_sync_page.dart";
|
||||
import "package:hash_wallet/src/screens/settings/display_settings_page.dart";
|
||||
import "package:hash_wallet/src/screens/settings/manage_nodes_page.dart";
|
||||
import "package:hash_wallet/src/screens/settings/other_settings_page.dart";
|
||||
import "package:hash_wallet/src/screens/settings/privacy_page.dart";
|
||||
import "package:hash_wallet/src/screens/settings/security_backup_page.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Every settings row opens its page and backs out", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
|
||||
final rowsUnderTest = <String, Type>{
|
||||
Routes.manageNodes: ManageNodesPage,
|
||||
Routes.privacyPage: PrivacyPage,
|
||||
Routes.otherSettingsPage: OtherSettingsPage,
|
||||
Routes.connectionSync: ConnectionSyncPage,
|
||||
Routes.displaySettingsPage: DisplaySettingsPage,
|
||||
Routes.securityBackupPage: SecurityBackupPage,
|
||||
Routes.aboutPage: AboutPage,
|
||||
};
|
||||
|
||||
await appLauncher.launchApp(testKey: "settings_nav_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
for (final entry in rowsUnderTest.entries) {
|
||||
tester.printToConsole("Opening settings row ${entry.key}");
|
||||
|
||||
await settingsRobot.openRow(entry.key);
|
||||
await settingsRobot.confirmLeafPageDisplayed(entry.value);
|
||||
|
||||
await settingsRobot.goBack();
|
||||
await settingsRobot.isDisplayed();
|
||||
}
|
||||
|
||||
await settingsRobot.dismissModal();
|
||||
await homePageRobot.isDisplayed();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:hash_wallet/src/screens/wallet_keys/wallet_keys_page.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/auth_flows.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
import "../../robots/show_keys_disclaimer_page_robot.dart";
|
||||
import "../../robots/wallet_keys_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Seed and keys page rejects a wrong pin and accepts the right one",
|
||||
(tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final authFlows = AuthFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
final walletKeysRobot = WalletKeysAndSeedPageRobot(tester);
|
||||
final disclaimerRobot = ShowKeysDisclaimerPageRobot(tester);
|
||||
|
||||
final wrongPin = [9, 9, 9, 9];
|
||||
|
||||
await appLauncher.launchApp(testKey: "show_keys_auth_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.showKeysDisclaimer);
|
||||
await disclaimerRobot.isDisplayed();
|
||||
await disclaimerRobot.tapShowKeys();
|
||||
|
||||
await authFlows.authenticateWithPin(pin: wrongPin);
|
||||
|
||||
// A wrong pin must keep the keys page locked away.
|
||||
await settingsRobot.settle(max: const Duration(seconds: 3));
|
||||
expect(find.byType(WalletKeysPage), findsNothing);
|
||||
expect(authFlows.isPinWidgetShown(), true);
|
||||
|
||||
await authFlows.authenticateWithPin();
|
||||
|
||||
await walletKeysRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.goBack();
|
||||
await settingsRobot.dismissModal();
|
||||
await homePageRobot.isDisplayed();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,85 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_info.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/auth_flows.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/wallet_edit_page_robot.dart";
|
||||
import "../../robots/wallet_list_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Deleting a wallet takes it off the list and out of storage", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final authFlows = AuthFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final walletListRobot = WalletListPageRobot(tester);
|
||||
final walletEditRobot = WalletEditPageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "wallet_delete_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
final deletedWallet = appStore.wallet!.name;
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
await onboardingFlows.createAdditionalWalletFromWalletList(WalletType.ethereum);
|
||||
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final keptWallet = appStore.wallet!.name;
|
||||
|
||||
expect(keptWallet, isNot(deletedWallet), reason: "The second wallet never became the open one");
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
await walletListRobot.isDisplayed();
|
||||
|
||||
await walletListRobot.openEditFor(deletedWallet);
|
||||
await walletEditRobot.isDisplayed();
|
||||
|
||||
await walletEditRobot.tapDelete();
|
||||
await authFlows.authenticateWithPin(required: false);
|
||||
|
||||
await walletEditRobot.confirmDelete();
|
||||
|
||||
await walletListRobot.isDisplayed();
|
||||
|
||||
final removed = await walletListRobot.pumpUntil(
|
||||
() => !walletListRobot.hasWallet(deletedWallet),
|
||||
timeout: const Duration(minutes: 1),
|
||||
);
|
||||
|
||||
expect(removed, true, reason: "$deletedWallet is still on the list after being deleted");
|
||||
|
||||
expect(
|
||||
walletListRobot.hasWallet(keptWallet),
|
||||
true,
|
||||
reason: "Deleting $deletedWallet took $keptWallet with it",
|
||||
);
|
||||
|
||||
final stored = await WalletInfo.getAll();
|
||||
final names = stored.map((wallet) => wallet.name).toList();
|
||||
|
||||
expect(names, isNot(contains(deletedWallet)));
|
||||
expect(names, contains(keptWallet));
|
||||
|
||||
expect(
|
||||
appStore.wallet?.name,
|
||||
keptWallet,
|
||||
reason: "Deleting another wallet changed which one is open",
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../flows/wallet_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A wallet added to an existing seed shares it and both stay reachable",
|
||||
(tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final walletFlows = WalletFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
const firstType = WalletType.solana;
|
||||
const secondType = WalletType.ethereum;
|
||||
|
||||
await appLauncher.launchApp(testKey: "wallet_group_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(firstType);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
final firstWalletName = appStore.wallet!.name;
|
||||
final sharedSeed = appStore.wallet!.seed;
|
||||
|
||||
expect(sharedSeed, isNotNull, reason: "The first wallet has no seed to share");
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
|
||||
await onboardingFlows.createWalletInGroupOf(secondType, firstWalletName);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final secondWalletName = appStore.wallet!.name;
|
||||
|
||||
expect(
|
||||
secondWalletName,
|
||||
isNot(firstWalletName),
|
||||
reason: "Adding to a group opened the wallet that was already there",
|
||||
);
|
||||
|
||||
expect(appStore.wallet?.type, secondType);
|
||||
|
||||
expect(
|
||||
appStore.wallet!.seed,
|
||||
sharedSeed,
|
||||
reason: "The wallet added to the group derived its own seed instead of sharing one",
|
||||
);
|
||||
|
||||
await walletFlows.switchToWallet(firstWalletName);
|
||||
|
||||
await homePageRobot.isDisplayed();
|
||||
await homePageRobot.hasWalletName(firstWalletName);
|
||||
|
||||
expect(appStore.wallet?.seed, sharedSeed);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_info.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/wallet_edit_page_robot.dart";
|
||||
import "../../robots/wallet_list_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A wallet can be renamed, but not onto a name already in use", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final walletListRobot = WalletListPageRobot(tester);
|
||||
final walletEditRobot = WalletEditPageRobot(tester);
|
||||
|
||||
const renamedTo = "Renamed Test Wallet";
|
||||
|
||||
await appLauncher.launchApp(testKey: "wallet_rename_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
final renamedWallet = appStore.wallet!.name;
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
await onboardingFlows.createAdditionalWalletFromWalletList(WalletType.ethereum);
|
||||
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final openWallet = appStore.wallet!.name;
|
||||
|
||||
expect(openWallet, isNot(renamedWallet), reason: "The second wallet never became the open one");
|
||||
|
||||
await dashboardRobot.openWalletsTab();
|
||||
await walletListRobot.isDisplayed();
|
||||
|
||||
await walletListRobot.openEditFor(renamedWallet);
|
||||
await walletEditRobot.isDisplayed();
|
||||
|
||||
await walletEditRobot.enterName(openWallet);
|
||||
await walletEditRobot.save();
|
||||
|
||||
await walletEditRobot.expectNameTakenRefusal();
|
||||
await walletEditRobot.dismissNameTakenRefusal();
|
||||
|
||||
await walletEditRobot.enterName(renamedTo);
|
||||
await walletEditRobot.save();
|
||||
|
||||
await walletListRobot.isDisplayed();
|
||||
|
||||
final renamed = await walletListRobot.pumpUntil(() => walletListRobot.hasWallet(renamedTo));
|
||||
|
||||
expect(renamed, true, reason: "The list never showed $renamedTo after the rename was saved");
|
||||
|
||||
expect(
|
||||
walletListRobot.hasWallet(renamedWallet),
|
||||
false,
|
||||
reason: "The list still shows $renamedWallet next to the name it was renamed to",
|
||||
);
|
||||
|
||||
final stored = await WalletInfo.getAll();
|
||||
final names = stored.map((wallet) => wallet.name).toList();
|
||||
|
||||
expect(names, contains(renamedTo));
|
||||
expect(names, isNot(contains(renamedWallet)));
|
||||
|
||||
expect(
|
||||
appStore.wallet?.name,
|
||||
openWallet,
|
||||
reason: "Renaming another wallet changed which one is open",
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../core/test_wallets.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("A 25 word monero seed restores through the legacy path", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
final legacySeed = TestWallets.moneroLegacySeed;
|
||||
|
||||
expect(
|
||||
legacySeed.split(" ").length,
|
||||
25,
|
||||
reason: "The legacy seed secret is not a 25 word seed, this suite would restore a polyseed",
|
||||
);
|
||||
|
||||
await appLauncher.launchApp(testKey: "monero_legacy_seed_test_app_key");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(WalletType.monero, seed: legacySeed);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
final appStore = getIt.get<AppStore>();
|
||||
|
||||
expect(appStore.wallet?.type, WalletType.monero);
|
||||
|
||||
expect(
|
||||
appStore.wallet?.seed?.split(" ").length,
|
||||
25,
|
||||
reason: "The wallet came back with a seed of a different length than the one restored",
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
import "package:hash_wallet/routes.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/manage_nodes_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_settings_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Switching nodes changes which one the wallet is pointed at", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final settingsRobot = NewSettingsPageRobot(tester);
|
||||
final nodesRobot = ManageNodesPageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "node_switching_test_app_key");
|
||||
|
||||
await onboardingFlows.createFirstWallet(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSettingsSheet();
|
||||
await settingsRobot.isDisplayed();
|
||||
|
||||
await settingsRobot.openRow(Routes.manageNodes);
|
||||
await nodesRobot.isDisplayed();
|
||||
|
||||
final initialNodeUri = nodesRobot.currentNodeUri();
|
||||
|
||||
expect(initialNodeUri, isNotEmpty, reason: "The wallet started with no node at all");
|
||||
|
||||
await nodesRobot.switchToAnotherNode();
|
||||
|
||||
expect(
|
||||
nodesRobot.currentNodeUri(),
|
||||
isNot(initialNodeUri),
|
||||
reason: "The node was confirmed but the wallet is still pointed at $initialNodeUri",
|
||||
);
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
import "../../robots/new_swap_page_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Swap sheet fetches a provider quote, no trade is created", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
final swapRobot = NewSwapPageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "swap_quote_test_app_key");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.openSwapSheet();
|
||||
await swapRobot.isDisplayed();
|
||||
|
||||
await swapRobot.enterDepositAmount("1");
|
||||
|
||||
await swapRobot.confirmQuoteReceived();
|
||||
|
||||
await swapRobot.dismissModal();
|
||||
await homePageRobot.isDisplayed();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Restored wallet connects to a node and starts syncing", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "sync_status_test_app_key");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(WalletType.bitcoin);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.confirmSyncIndicatorShown();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Tapping a transaction opens the details of that transaction", (tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "transaction_details_test_app_key");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
await homePageRobot.confirmTransactionHistoryVisible();
|
||||
|
||||
await homePageRobot.openAllTransactions();
|
||||
await homePageRobot.confirmAllTransactionsVisible();
|
||||
|
||||
final tapped = homePageRobot.firstTransactionIdInAllView();
|
||||
|
||||
expect(tapped, isNotEmpty, reason: "The tile carries no transaction id to check against");
|
||||
|
||||
await homePageRobot.openFirstTransactionDetails();
|
||||
|
||||
// A list that hands the wrong transaction to the details screen shows one person's
|
||||
// amounts under another's id, and nothing on the screen would say so.
|
||||
expect(
|
||||
homePageRobot.openedTransactionId(),
|
||||
tapped,
|
||||
reason: "The details opened for a different transaction than the one tapped",
|
||||
);
|
||||
|
||||
homePageRobot.hasTransactionIdRow();
|
||||
});
|
||||
}
|
||||
@@ -0,0 +1,37 @@
|
||||
import "package:hash_wallet/di.dart";
|
||||
import "package:hash_wallet/store/app_store.dart";
|
||||
import "package:cw_core/wallet_type.dart";
|
||||
import "package:flutter_test/flutter_test.dart";
|
||||
import "package:integration_test/integration_test.dart";
|
||||
|
||||
import "../../core/app_launcher.dart";
|
||||
import "../../flows/onboarding_flows.dart";
|
||||
import "../../robots/home_page_robot.dart";
|
||||
import "../../robots/new_dashboard_robot.dart";
|
||||
|
||||
void main() {
|
||||
IntegrationTestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
integrationTest("Transaction history renders for a wallet with known transactions",
|
||||
(tester) async {
|
||||
final appLauncher = AppLauncher(tester);
|
||||
final onboardingFlows = OnboardingFlows(tester);
|
||||
final dashboardRobot = NewDashboardRobot(tester);
|
||||
final homePageRobot = HomePageRobot(tester);
|
||||
|
||||
await appLauncher.launchApp(testKey: "transaction_history_test_app_key");
|
||||
|
||||
await onboardingFlows.restoreFirstWalletFromSeed(WalletType.solana);
|
||||
|
||||
await dashboardRobot.isDisplayed();
|
||||
await homePageRobot.isDisplayed();
|
||||
|
||||
expect(getIt.get<AppStore>().wallet?.type, WalletType.solana);
|
||||
|
||||
await homePageRobot.confirmTransactionHistoryVisible();
|
||||
|
||||
await homePageRobot.openAllTransactions();
|
||||
|
||||
await homePageRobot.confirmAllTransactionsVisible();
|
||||
});
|
||||
}
|
||||
Reference in New Issue
Block a user