From 7547442e398a2215911aa3cc0e9c53145c28f7c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Tinkl?= Date: Thu, 2 Jan 2025 17:01:42 +0100 Subject: [PATCH] fix(OnboardingFlow): collect `enableBiometrics` and `seedphrase` data - extend the tests to verify whether we collected the correct data - restore the "pointing hand" cursor on clickable elements - some minor improvements --- .../qmlTests/tests/tst_OnboardingLayout.qml | 42 +++++++++++++++++++ .../Onboarding2/KeycardCreateProfileFlow.qml | 6 ++- .../AppLayouts/Onboarding2/OnboardingFlow.qml | 22 +++++----- .../Onboarding2/OnboardingLayout.qml | 22 +++++----- .../Onboarding2/OnboardingStackView.qml | 1 - .../Onboarding2/UseRecoveryPhraseFlow.qml | 2 +- 6 files changed, 72 insertions(+), 23 deletions(-) diff --git a/storybook/qmlTests/tests/tst_OnboardingLayout.qml b/storybook/qmlTests/tests/tst_OnboardingLayout.qml index 65a5a00b2a..8637e5056a 100644 --- a/storybook/qmlTests/tests/tst_OnboardingLayout.qml +++ b/storybook/qmlTests/tests/tst_OnboardingLayout.qml @@ -281,6 +281,12 @@ Item { // FINISH tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.CreateProfileWithPassword) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, mockDriver.dummyNewPassword) + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, "") + compare(resultData.seedphrase, "") } // FLOW: Create Profile -> Use a recovery phrase (create profile with seedphrase) @@ -372,6 +378,12 @@ Item { // FINISH tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.CreateProfileWithSeedphrase) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, mockDriver.dummyNewPassword) + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, "") + compare(resultData.seedphrase, mockDriver.mnemonic) } function test_flow_createProfile_withKeycardAndNewSeedphrase_data() { @@ -535,6 +547,12 @@ Item { // FINISH tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.CreateProfileWithKeycardNewSeedphrase) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, "") + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, !!data.pin ? data.pin : "123321") + compare(resultData.seedphrase, "") // TODO check seed here as well? } function test_flow_createProfile_withKeycardAndExistingSeedphrase_data() { @@ -640,6 +658,12 @@ Item { // FINISH tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.CreateProfileWithKeycardExistingSeedphrase) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, "") + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, !!data.pin ? data.pin : "123321") + compare(resultData.seedphrase, mockDriver.mnemonic) } // FLOW: Log in -> Log in with recovery phrase @@ -727,6 +751,12 @@ Item { tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.LoginWithSeedphrase) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, mockDriver.dummyNewPassword) + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, "") + compare(resultData.seedphrase, mockDriver.mnemonic) } // FLOW: Log in -> Log in by syncing @@ -813,6 +843,12 @@ Item { // FINISH tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.LoginWithSyncing) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, "") + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, "") + compare(resultData.seedphrase, "") } // FLOW: Log in -> Log in with Keycard @@ -872,6 +908,12 @@ Item { // FINISH tryCompare(finishedSpy, "count", 1) compare(finishedSpy.signalArguments[0][0], Onboarding.SecondaryFlow.LoginWithKeycard) + const resultData = finishedSpy.signalArguments[0][1] + verify(!!resultData) + compare(resultData.password, "") + compare(resultData.enableBiometrics, data.biometrics && data.bioEnabled) + compare(resultData.keycardPin, mockDriver.existingPin) + compare(resultData.seedphrase, "") } } } diff --git a/ui/app/AppLayouts/Onboarding2/KeycardCreateProfileFlow.qml b/ui/app/AppLayouts/Onboarding2/KeycardCreateProfileFlow.qml index 36b148bb1d..70473ab899 100644 --- a/ui/app/AppLayouts/Onboarding2/KeycardCreateProfileFlow.qml +++ b/ui/app/AppLayouts/Onboarding2/KeycardCreateProfileFlow.qml @@ -24,6 +24,7 @@ SQUtils.QObject { signal loginWithKeycardRequested signal keycardFactoryResetRequested signal keycardPinCreated(string pin) + signal seedphraseSubmitted(string seedphrase) signal keypairAddTryAgainRequested signal reloadKeycardRequested @@ -152,7 +153,10 @@ SQUtils.QObject { title: qsTr("Create profile on empty Keycard using a recovery phrase") isSeedPhraseValid: root.isSeedPhraseValid - onSeedphraseSubmitted: root.stackView.push(keycardCreatePinPage) + onSeedphraseSubmitted: (seedphrase) => { + root.seedphraseSubmitted(seedphrase) + root.stackView.push(keycardCreatePinPage) + } StackView.onActivated: d.fromBackupSeedphrase = true } diff --git a/ui/app/AppLayouts/Onboarding2/OnboardingFlow.qml b/ui/app/AppLayouts/Onboarding2/OnboardingFlow.qml index b0a2da909f..8115310a79 100644 --- a/ui/app/AppLayouts/Onboarding2/OnboardingFlow.qml +++ b/ui/app/AppLayouts/Onboarding2/OnboardingFlow.qml @@ -19,9 +19,9 @@ SQUtils.QObject { required property int remainingAttempts required property int splashScreenDurationMs - property bool biometricsAvailable - property bool displayKeycardPromoBanner - property bool networkChecksEnabled + required property bool biometricsAvailable + required property bool displayKeycardPromoBanner + required property bool networkChecksEnabled // functions required property var passwordStrengthScoreFunction @@ -145,8 +145,8 @@ SQUtils.QObject { isSeedPhraseValid: root.isSeedPhraseValid passwordStrengthScoreFunction: root.passwordStrengthScoreFunction - onSeedphraseSubmitted: root.seedphraseSubmitted(seedphrase) - onSetPasswordRequested: root.setPasswordRequested(password) + onSeedphraseSubmitted: (seedphrase) => root.seedphraseSubmitted(seedphrase) + onSetPasswordRequested: (password) => root.setPasswordRequested(password) onFinished: d.pushOrSkipBiometricsPage() } @@ -162,7 +162,7 @@ SQUtils.QObject { splashScreenDurationMs: root.splashScreenDurationMs onReloadKeycardRequested: root.reloadKeycardRequested() - onKeycardPinCreated: root.keycardPinCreated(pin) + onKeycardPinCreated: (pin) => root.keycardPinCreated(pin) onLoginWithKeycardRequested: loginWithKeycardFlow.init() onCreateProfileWithoutKeycardRequested: { @@ -172,6 +172,8 @@ SQUtils.QObject { stackView.replace(page, createProfilePage, StackView.PopTransition) } + onSeedphraseSubmitted: (seedphrase) => root.seedphraseSubmitted(seedphrase) + onFinished: (fromBackupSeedphrase) => { d.flow = fromBackupSeedphrase ? Onboarding.SecondaryFlow.CreateProfileWithKeycardExistingSeedphrase @@ -190,8 +192,8 @@ SQUtils.QObject { splashScreenDurationMs: root.splashScreenDurationMs - onSyncProceedWithConnectionString: - root.syncProceedWithConnectionString(connectionString) + onSyncProceedWithConnectionString: (connectionString) => + root.syncProceedWithConnectionString(connectionString) onLoginWithSeedphraseRequested: { d.flow = Onboarding.SecondaryFlow.LoginWithSeedphrase @@ -213,7 +215,7 @@ SQUtils.QObject { displayKeycardPromoBanner: root.displayKeycardPromoBanner tryToSetPinFunction: root.tryToSetPinFunction - onKeycardPinEntered: root.keycardPinEntered(pin) + onKeycardPinEntered: (pin) => root.keycardPinEntered(pin) onReloadKeycardRequested: root.reloadKeycardRequested() onCreateProfileWithEmptyKeycardRequested: keycardCreateProfileFlow.init() @@ -227,7 +229,7 @@ SQUtils.QObject { id: enableBiometricsPage EnableBiometricsPage { - onEnableBiometricsRequested: { + onEnableBiometricsRequested: (enable) => { root.enableBiometricsRequested(enable) root.finished(d.flow) } diff --git a/ui/app/AppLayouts/Onboarding2/OnboardingLayout.qml b/ui/app/AppLayouts/Onboarding2/OnboardingLayout.qml index 05a97be3a8..37525feff9 100644 --- a/ui/app/AppLayouts/Onboarding2/OnboardingLayout.qml +++ b/ui/app/AppLayouts/Onboarding2/OnboardingLayout.qml @@ -86,7 +86,7 @@ Page { objectName: "stack" anchors.fill: parent - property bool backAvailable: + readonly property bool backAvailable: stack.currentItem ? (stack.currentItem.backAvailableHint ?? true) : false } @@ -95,6 +95,7 @@ Page { anchors.fill: parent acceptedButtons: Qt.BackButton enabled: stack.depth > 1 && !stack.busy + cursorShape: undefined onClicked: stack.pop() } @@ -137,17 +138,17 @@ Page { tryToSetPinFunction: root.onboardingStore.setPin remainingAttempts: root.onboardingStore.keycardRemainingPinAttempts - onKeycardPinCreated: { + onKeycardPinCreated: (pin) => { d.keycardPin = pin root.onboardingStore.setPin(pin) } - onKeycardPinEntered: { + onKeycardPinEntered: (pin) => { d.keycardPin = pin root.onboardingStore.setPin(pin) } - onShareUsageDataRequested: { + onShareUsageDataRequested: (enabled) => { root.metricsStore.toggleCentralizedMetrics(enabled) Global.addCentralizedMetricIfEnabled( "usage_data_shared", @@ -155,14 +156,15 @@ Page { localAppSettings.metricsPopupSeen = true } - onSyncProceedWithConnectionString: - root.onboardingStore.inputConnectionStringForBootstrapping( - connectionString) + onSyncProceedWithConnectionString: (connectionString) => + root.onboardingStore.inputConnectionStringForBootstrapping(connectionString) - onSeedphraseSubmitted: d.seedphrase = seedphrase - onSetPasswordRequested: d.password = password + onSeedphraseSubmitted: (seedphrase) => d.seedphrase = seedphrase + onSetPasswordRequested: (password) => d.password = password - onFinished: d.finishFlow(flow) + onEnableBiometricsRequested: (enabled) => d.enableBiometrics = enabled + + onFinished: (flow) => d.finishFlow(flow) } Connections { diff --git a/ui/app/AppLayouts/Onboarding2/OnboardingStackView.qml b/ui/app/AppLayouts/Onboarding2/OnboardingStackView.qml index ef019e269d..2ca77acce6 100644 --- a/ui/app/AppLayouts/Onboarding2/OnboardingStackView.qml +++ b/ui/app/AppLayouts/Onboarding2/OnboardingStackView.qml @@ -1,7 +1,6 @@ import QtQuick 2.15 import QtQuick.Controls 2.15 - StackView { id: root diff --git a/ui/app/AppLayouts/Onboarding2/UseRecoveryPhraseFlow.qml b/ui/app/AppLayouts/Onboarding2/UseRecoveryPhraseFlow.qml index 18aecbb1c0..96f183f8d3 100644 --- a/ui/app/AppLayouts/Onboarding2/UseRecoveryPhraseFlow.qml +++ b/ui/app/AppLayouts/Onboarding2/UseRecoveryPhraseFlow.qml @@ -29,7 +29,7 @@ SQUtils.QObject { title: qsTr("Create profile using a recovery phrase") isSeedPhraseValid: root.isSeedPhraseValid - onSeedphraseSubmitted: { + onSeedphraseSubmitted: (seedphrase) => { root.seedphraseSubmitted(seedphrase) root.stackView.push(createPasswordPage) }