CW-827 CI/CD update (#1948)

* CI update
- use existing build outputs in build_monero_all.sh
- update $HOME, fix gh actions
- add secrets earlier in the runtime (potentially speed up 'Build generated code' step)
- add windows dockerfile
- add linux/android dockerfile
- update android/linux ci script

* [skip slack] [run tests] Run tests on CI, fix tests

* [skip slack] [run tests] force enable kvm in android

* [skip slack] [run tests] remove inexisting flag

* [run tests] [skip slack] update tests

* add extra dependencies [skip ci]

* [skip slack] [run tests] Add secrets

* [skip slack] [run tests] Timeout test cases, continue on error

* [skip slack] [run tests] Xvfb fix, timeout fix

* [skip slack] [run tests] Start dbus to clean up the logs, use SIGKILL

* [skip slack] [run tests] Enable network manager

* [skip slack] [run tests] Screen record test, resize screen

* [skip slack] [run tests] Improve status report for tests

* [skip slack] [run tests] Increase framerate

* [skip slack] [run tests] Remove test that I am unable to fix locally easily from CI

* [skip slack] [run tests] Simplify ffmpeg command

* [skip slack] [run tests] Increase timeout, add comment

* [skip slack] Update dockerfile, migrate from mrcyjanek to cake-tech for the ghcr org

* Update lib/entities/default_settings_migration.dart

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>

---------

Co-authored-by: Omar Hatem <omarh.ismail1@gmail.com>
This commit is contained in:
cyan 2025-01-15 12:09:59 +01:00 committed by GitHub
parent 80b116b8ae
commit 3e10023e18
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
32 changed files with 862 additions and 554 deletions

View file

@ -32,6 +32,11 @@ class CommonTestCases {
expect(textWidget, hasWidget ? findsOneWidget : findsNothing);
}
void hasTextAtLestOnce(String text, {bool hasWidget = true}) {
final textWidget = find.text(text);
expect(textWidget, hasWidget ? findsAny : findsNothing);
}
void hasType<T>() {
final typeWidget = find.byType(T);
expect(typeWidget, findsOneWidget);

View file

@ -1,3 +1,5 @@
import 'dart:io';
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/reactions/bip39_wallet_utils.dart';
import 'package:cake_wallet/wallet_types.g.dart';
@ -85,6 +87,7 @@ class CommonTestFlows {
await _confirmPreSeedInfo();
await _confirmWalletDetails();
await _commonTestCases.defaultSleepTime();
}
//* ========== Handles flow from welcome to restoring wallet from seeds ===============
@ -168,8 +171,8 @@ class CommonTestFlows {
await _walletListPageRobot.navigateToRestoreWalletOptionsPage();
await _commonTestCases.defaultSleepTime();
await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
await _commonTestCases.defaultSleepTime();
if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
if (!Platform.isLinux) await _commonTestCases.defaultSleepTime();
await _selectWalletTypeForWallet(walletType);
await _commonTestCases.defaultSleepTime();
@ -180,6 +183,7 @@ class CommonTestFlows {
//* ========== Handles setting up pin code for wallet on first install ===============
Future<void> setupPinCodeForWallet(List<int> pin) async {
if (Platform.isLinux) return;
// ----------- SetupPinCode Page -------------
// Confirm initial defaults - Widgets to be displayed etc
await _setupPinCodeRobot.isSetupPinCodePage();
@ -212,7 +216,7 @@ class CommonTestFlows {
await _welcomePageRobot.navigateToRestoreWalletPage();
await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
if (!Platform.isLinux) await _restoreOptionsPageRobot.navigateToRestoreFromSeedsOrKeysPage();
await _selectWalletTypeForWallet(walletTypeToRestore);
}
@ -234,6 +238,12 @@ class CommonTestFlows {
await _newWalletPageRobot.generateWalletName();
if (Platform.isLinux) {
// manual pin input
await _restoreFromSeedOrKeysPageRobot.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
await _restoreFromSeedOrKeysPageRobot.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
}
await _newWalletPageRobot.onNextButtonPressed();
}
@ -252,11 +262,15 @@ class CommonTestFlows {
_walletSeedPageRobot.confirmWalletSeedReminderDisplays();
await _walletSeedPageRobot.onCopySeedsButtonPressed();
// await _walletSeedPageRobot.onCopySeedsButtonPressed();
await _walletSeedPageRobot.onNextButtonPressed();
await _walletSeedPageRobot.onConfirmButtonOnSeedAlertDialogPressed();
await _walletSeedPageRobot.onSeedPageVerifyButtonPressed();
// Turns out the popup about "Copied to clipboard" prevents
//the button from being pressed on the first try, by just
//tapping it again we fix it.
// await _walletSeedPageRobot.onSeedPageVerifyButtonPressed();
await _walletSeedPageRobot.onOpenWalletButtonPressed();
}
//* Main Restore Actions - On the RestoreFromSeed/Keys Page - Restore from Seeds Action
@ -277,6 +291,12 @@ class CommonTestFlows {
.enterBlockHeightForWalletRestore(secrets.moneroTestWalletBlockHeight);
}
if (Platform.isLinux) {
// manual pin input
await _restoreFromSeedOrKeysPageRobot.enterPasswordForWalletRestore(CommonTestConstants.pin.join(""));
await _restoreFromSeedOrKeysPageRobot.enterPasswordRepeatForWalletRestore(CommonTestConstants.pin.join(""));
}
await _restoreFromSeedOrKeysPageRobot.onRestoreWalletButtonPressed();
}

View file

@ -67,6 +67,11 @@ void main() {
await authPageRobot.enterPinCode(CommonTestConstants.pin);
}
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
if (onAuthPageDesktop) {
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
}
// ----------- Exchange Confirm Page -------------
await exchangeConfirmPageRobot.isExchangeConfirmPage();

View file

@ -20,6 +20,11 @@ class AuthPageRobot extends PinCodeWidgetRobot {
return hasPin;
}
bool onAuthPageDesktop() {
final hasWalletPasswordInput = find.byKey(ValueKey('enter_wallet_password'));
return hasWalletPasswordInput.tryEvaluate();
}
Future<void> isAuthPage() async {
await commonTestCases.isSpecificPage<AuthPage>();
}

View file

@ -24,6 +24,20 @@ class PinCodeWidgetRobot {
commonTestCases.hasValueKey('pin_code_button_0_key');
}
Future<void> enterPassword(String password, {int pumpDuration = 100}) async {
await commonTestCases.enterText(
password,
'enter_wallet_password',
);
await tester.pumpAndSettle();
await commonTestCases.tapItemByKey(
'unlock',
);
await tester.pumpAndSettle();
await commonTestCases.defaultSleepTime();
}
Future<void> enterPinCode(List<int> pinCode, {int pumpDuration = 100}) async {
for (int pin in pinCode) {
await commonTestCases.tapItemByKey(

View file

@ -1,7 +1,9 @@
import 'package:cake_wallet/entities/seed_type.dart';
import 'package:cake_wallet/generated/i18n.dart';
import 'package:cake_wallet/src/screens/restore/wallet_restore_page.dart';
import 'package:cake_wallet/src/widgets/seed_widget.dart';
import 'package:cake_wallet/src/widgets/validable_annotated_editable_text.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import '../components/common_test_cases.dart';
@ -65,12 +67,28 @@ class RestoreFromSeedOrKeysPageRobot {
Future<void> enterSeedPhraseForWalletRestore(String text) async {
ValidatableAnnotatedEditableTextState seedTextState =
await tester.state(find.byType(ValidatableAnnotatedEditableText));
await tester.state(find.byType(ValidatableAnnotatedEditableText));
seedTextState.widget.controller.text = text;
await tester.pumpAndSettle();
}
Future<void> enterPasswordForWalletRestore(String text) async {
await commonTestCases.enterText(
text,
'password',
);
await tester.pumpAndSettle();
}
Future<void> enterPasswordRepeatForWalletRestore(String text) async {
await commonTestCases.enterText(
text,
'repeat_wallet_password',
);
await tester.pumpAndSettle();
}
Future<void> enterBlockHeightForWalletRestore(String blockHeight) async {
await commonTestCases.enterText(
blockHeight,

View file

@ -183,32 +183,15 @@ class SendPageRobot {
}
Future<void> _handleAuthPage() async {
tester.printToConsole('Inside _handleAuth');
await tester.pump();
tester.printToConsole('starting auth checks');
final authPage = authPageRobot.onAuthPage();
tester.printToConsole('hasAuth:$authPage');
if (authPage) {
await tester.pump();
tester.printToConsole('Starting inner _handleAuth loop checks');
try {
await authPageRobot.enterPinCode(CommonTestConstants.pin, pumpDuration: 500);
tester.printToConsole('Auth done');
await tester.pump();
tester.printToConsole('Auth pump done');
} catch (e) {
tester.printToConsole('Auth failed, retrying');
await tester.pump();
_handleAuthPage();
}
final onAuthPage = authPageRobot.onAuthPage();
if (onAuthPage) {
await authPageRobot.enterPinCode(CommonTestConstants.pin);
}
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
if (onAuthPageDesktop) {
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
}
await tester.pump();
}
Future<void> handleSendResult() async {
@ -221,7 +204,7 @@ class SendPageRobot {
tester.printToConsole('Has an Error in the handle: $hasError');
int maxRetries = 20;
int maxRetries = 3;
int retries = 0;
while (hasError && retries < maxRetries) {

View file

@ -14,8 +14,13 @@ class WalletSeedPageRobot {
await commonTestCases.isSpecificPage<WalletSeedPage>();
}
Future<void> onNextButtonPressed() async {
await commonTestCases.tapItemByKey('wallet_seed_page_next_button_key');
Future<void> onSeedPageVerifyButtonPressed() async {
await commonTestCases.tapItemByKey('wallet_seed_page_verify_seed_button_key');
await commonTestCases.defaultSleepTime();
}
Future<void> onOpenWalletButtonPressed() async {
await commonTestCases.tapItemByKey('wallet_seed_page_open_wallet_button_key');
await commonTestCases.defaultSleepTime();
}
@ -38,11 +43,14 @@ class WalletSeedPageRobot {
final walletSeeds = walletSeedViewModel.seed;
commonTestCases.hasText(walletName);
commonTestCases.hasText(walletSeeds);
final seedList = walletSeeds.trim().split(" ");
for (final seedWord in seedList) {
commonTestCases.hasTextAtLestOnce(seedWord);
}
}
void confirmWalletSeedReminderDisplays() {
commonTestCases.hasText(S.current.seed_reminder);
commonTestCases.hasText(S.current.cake_seeds_save_disclaimer);
}
Future<void> onSaveSeedsButtonPressed() async {

View file

@ -1,9 +1,13 @@
import 'dart:io';
import 'package:cake_wallet/wallet_types.g.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:integration_test/integration_test.dart';
import '../components/common_test_cases.dart';
import '../components/common_test_constants.dart';
import '../components/common_test_flows.dart';
import '../robots/auth_page_robot.dart';
@ -95,6 +99,10 @@ Future<void> _confirmSeedsFlowForWalletType(
await authPageRobot.enterPinCode(CommonTestConstants.pin);
}
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
if (onAuthPageDesktop) {
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
}
await tester.pumpAndSettle();
await walletKeysAndSeedPageRobot.isWalletKeysAndSeedPage();

View file

@ -56,6 +56,10 @@ void main() {
await authPageRobot.enterPinCode(CommonTestConstants.pin);
}
final onAuthPageDesktop = authPageRobot.onAuthPageDesktop();
if (onAuthPageDesktop) {
await authPageRobot.enterPassword(CommonTestConstants.pin.join(""));
}
await exchangeConfirmPageRobot.onSavedTradeIdButtonPressed();
await exchangeTradePageRobot.onGotItButtonPressed();
});

View file

@ -1,4 +1,7 @@
import 'dart:io';
import 'package:cake_wallet/wallet_types.g.dart';
import 'package:cw_core/utils/print_verbose.dart';
import 'package:cw_core/wallet_type.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';