Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(e2e): refactor testing flow #325

Merged
merged 4 commits into from
Aug 16, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
119 changes: 119 additions & 0 deletions integration_test/e2e_mnemonic_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:my_wit_wallet/screens/create_wallet/generate_mnemonic_card.dart';
import 'package:my_wit_wallet/screens/dashboard/view/dashboard_screen.dart';
import 'package:my_wit_wallet/util/storage/database/wallet.dart';
import 'package:my_wit_wallet/widgets/PaddedButton.dart';
import 'package:my_wit_wallet/widgets/labeled_checkbox.dart';
import 'test_utils.dart';

Future<void> e2eImportMnemonicTest(WidgetTester tester) async {
await initializeTest(tester);

/// Assess what is on the screen
walletsExist = isTextOnScreen("Unlock wallet");
bool biometricsActive = isTextOnScreen("CANCEL");

/// Cancel the Biometrics popup
if (walletsExist && biometricsActive) await tapButton(tester, "CANCEL");

if (walletsExist) {
/// Login Screen
await enterText(tester, TextFormField, password);
await tapButton(tester, "Unlock wallet");

/// Dashboard
/// Tap on the first PaddedButton on the screen, which is the identicon
/// and brings up the wallet list.
await tapButton(tester, PaddedButton, index: 0);
await tapButton(tester, FontAwesomeIcons.circlePlus);
}

/// Create or Import Wallet
await tapButton(tester, "Import wallet");
await tapButton(tester, "Import from secret security phrase");

/// Wallet Security
await scrollUntilVisible(
tester, widgetByLabel("I will be careful, I promise!"));
await tapButton(tester, LabeledCheckbox);
await tapButton(tester, "Continue");

/// Enter Mnemonic
await enterText(tester, TextField, mnemonic);
await tapButton(tester, "Continue");

/// Enter Wallet Name
await enterText(tester, TextField, "Test Wallet");
await tapButton(tester, "Continue");

/// If the wallet database does not exist we need to enter the password.
if (!walletsExist) {
await enterText(tester, TextFormField, password, index: 0);
await enterText(tester, TextFormField, password, index: 1);
await tapButton(tester, "Continue");
}

/// Get the currentWallet loaded in the dashboard
final DashboardScreenState dashboardScreenState =
tester.state(widgetByType(DashboardScreen));
dashboardScreenState.currentWallet!.printDebug();
Wallet? currentWallet = dashboardScreenState.currentWallet;
/// Verify the imported wallet and the current address
expect(currentWallet!.externalAccounts[0]!.address,
"wit174la8pevl74hczcpfepgmt036zkmjen4hu8zzs");
}

Future<void> e2eCreateMnemonicTest(WidgetTester tester) async {
await initializeTest(tester);

/// Assess what is on the screen
walletsExist = isTextOnScreen("Unlock wallet");
bool biometricsActive = isTextOnScreen("CANCEL");

/// Cancel the Biometrics popup
if (walletsExist && biometricsActive) await tapButton(tester, "CANCEL");

if (walletsExist) {
/// Login Screen
await enterText(tester, TextFormField, password);
await tapButton(tester, "Unlock wallet");

/// Dashboard
/// Tap on the first PaddedButton on the screen, which is the identicon
/// and brings up the wallet list.
await tapButton(tester, PaddedButton, index: 0);
await tapButton(tester, FontAwesomeIcons.circlePlus);
}

/// Create or Import Wallet
await tapButton(tester, "Create new wallet");

/// Wallet Security
await scrollUntilVisible(
tester, widgetByLabel("I will be careful, I promise!"));
await tapButton(tester, LabeledCheckbox);
await tapButton(tester, "Continue");

/// Get the generated mnemonic
final GenerateMnemonicCardState generateMnemonicCardState =
tester.state(widgetByType(GenerateMnemonicCard));
String generatedMnemonic = generateMnemonicCardState.mnemonic;
await tapButton(tester, "Continue");

/// Enter Mnemonic
await enterText(tester, TextField, generatedMnemonic);
await tapButton(tester, "Continue");

/// Enter Wallet Name
await enterText(tester, TextField, "Test Wallet");
await tapButton(tester, "Continue");

/// If the wallet database does not exist we need to enter the password.
if (!walletsExist) {
await enterText(tester, TextFormField, password, index: 0);
await enterText(tester, TextFormField, password, index: 1);
await tapButton(tester, "Continue");
}
}
64 changes: 0 additions & 64 deletions integration_test/import_mnemonic_test.dart

This file was deleted.

9 changes: 9 additions & 0 deletions integration_test/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import "e2e_mnemonic_test.dart";
import 'package:flutter_test/flutter_test.dart';

void main() async {
group("End To End Mnemonic Tests", () {
testWidgets("Create Mnemonic Test", e2eCreateMnemonicTest);
testWidgets("Import Mnemonic Test", e2eImportMnemonicTest);
});
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,36 @@
import 'package:flutter/material.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:my_wit_wallet/main.dart' as myWitWallet;
import 'package:my_wit_wallet/widgets/PaddedButton.dart';

bool walletsExist = false;
int defaultDelay = int.parse(dotenv.env['DELAY']!);
String password = dotenv.env['PASSWORD'] ?? "password";
String mnemonic = dotenv.env['MNEMONIC'] ??
"abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon abandon about";

Finder widgetByType(Type type) => find.byType(type);

Finder widgetByText(String text) => find.text(text);

Finder widgetByIcon(IconData icon) => find.byIcon(icon);

Finder widgetByLabel(String label) => find.bySemanticsLabel(label);
const int defaultDelay = 1000;

Future<bool> tapButton(WidgetTester tester, dynamic value,
{int? index, bool delay = true, int milliseconds = defaultDelay}) async {
Future<void> initializeTest(WidgetTester tester) async {
myWitWallet.main();
await tester.pumpAndSettle();
}

Future<bool> tapButton(
WidgetTester tester,
dynamic value, {
int? index,
bool delay = true,
int? milliseconds,
}) async {
Finder finder;
switch (value.runtimeType) {
case Type:
Expand All @@ -35,19 +55,21 @@ Future<bool> tapButton(WidgetTester tester, dynamic value,
break;
}
}

await tester.tap(index != null ? finder.at(index) : finder);
await tester.pumpAndSettle();
if (delay) {
await Future.delayed(Duration(milliseconds: milliseconds));
await Future.delayed(Duration(milliseconds: milliseconds ?? defaultDelay));
}
return true;
}

Future<bool> tapButtonByName(WidgetTester tester, String text,
{int index = 0,
bool delay = true,
int milliseconds = defaultDelay}) async =>
Future<bool> tapButtonByName(
WidgetTester tester,
String text, {
int index = 0,
bool delay = true,
int? milliseconds,
}) async =>
await tapButton(
tester,
text,
Expand All @@ -56,10 +78,13 @@ Future<bool> tapButtonByName(WidgetTester tester, String text,
milliseconds: milliseconds,
);

Future<bool> tapButtonByType(WidgetTester tester, Type type,
{int index = 0,
bool delay = true,
int milliseconds = defaultDelay}) async =>
Future<bool> tapButtonByType(
WidgetTester tester,
Type type, {
int index = 0,
bool delay = true,
int? milliseconds,
}) async =>
await tapButton(
tester,
type,
Expand All @@ -68,10 +93,13 @@ Future<bool> tapButtonByType(WidgetTester tester, Type type,
milliseconds: milliseconds,
);

Future<bool> tapButtonByIndex(WidgetTester tester, dynamic data,
{int index = 0,
bool delay = true,
int milliseconds = defaultDelay}) async =>
Future<bool> tapButtonByIndex(
WidgetTester tester,
dynamic data, {
int index = 0,
bool delay = true,
int? milliseconds,
}) async =>
await tapButton(
tester,
data,
Expand All @@ -80,10 +108,13 @@ Future<bool> tapButtonByIndex(WidgetTester tester, dynamic data,
milliseconds: milliseconds,
);

Future<bool> tapButtonByIcon(WidgetTester tester, IconData icon,
{int index = 0,
bool delay = true,
int milliseconds = defaultDelay}) async =>
Future<bool> tapButtonByIcon(
WidgetTester tester,
IconData icon, {
int index = 0,
bool delay = true,
int? milliseconds,
}) async =>
await tapButton(
tester,
icon,
Expand All @@ -92,10 +123,13 @@ Future<bool> tapButtonByIcon(WidgetTester tester, IconData icon,
milliseconds: milliseconds,
);

Future<bool> tapButtonByLabel(WidgetTester tester, String label,
{int index = 0,
bool delay = true,
int milliseconds = defaultDelay}) async =>
Future<bool> tapButtonByLabel(
WidgetTester tester,
String label, {
int index = 0,
bool delay = true,
int? milliseconds,
}) async =>
await tapButton(
tester,
label,
Expand All @@ -104,27 +138,38 @@ Future<bool> tapButtonByLabel(WidgetTester tester, String label,
milliseconds: milliseconds,
);

Future<bool> enterText(WidgetTester tester, Type type, String text,
{int? index, bool delay = true, int milliseconds = defaultDelay}) async {
Future<bool> enterText(
WidgetTester tester,
Type type,
String text, {
int? index,
bool delay = true,
int? milliseconds,
}) async {
index != null
? await tester.enterText(widgetByType(type).at(index), text)
: await tester.enterText(widgetByType(type), text);
await tester.pumpAndSettle();
if (delay) {
await Future.delayed(Duration(milliseconds: milliseconds));
await Future.delayed(Duration(milliseconds: milliseconds ?? defaultDelay));
}
return true;
}

enum ScrollDirection { Up, Down, Left, Right }

Future<bool> scrollUntilVisible(WidgetTester tester, Finder finder,
{int index = 0, bool delay = true, int milliseconds = defaultDelay}) async {
Future<bool> scrollUntilVisible(
WidgetTester tester,
Finder finder, {
int index = 0,
bool delay = true,
int? milliseconds,
}) async {
await tester.scrollUntilVisible(finder, -100.0,
duration: Duration(milliseconds: 500), maxScrolls: 100);
await tester.pumpAndSettle();
if (delay) {
await Future.delayed(Duration(milliseconds: milliseconds));
await Future.delayed(Duration(milliseconds: milliseconds ?? defaultDelay));
}
return true;
}
Expand Down
1 change: 1 addition & 0 deletions lib/app.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ Widget _buildWithTheme(BuildContext context, ThemeState state) {
parent: RangeMaintainingScrollPhysics())),
title: 'myWitWallet',
home: LoginScreen(),
initialRoute: LoginScreen.route,
theme: state.themeData,
routes: {
CreateWalletScreen.route: (context) => CreateWalletScreen(),
Expand Down
Loading