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

Test recovery key #2429

Merged
merged 8 commits into from
Feb 22, 2024
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
13 changes: 7 additions & 6 deletions .github/workflows/maestro.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@ jobs:
# app-file should point to an x86 compatible APK file, so upload the x86_64 one (much smaller than the universal APK).
app-file: app/build/outputs/apk/gplay/debug/app-gplay-x86_64-debug.apk
env: |
USERNAME=maestroelement
PASSWORD=${{ secrets.MATRIX_MAESTRO_ACCOUNT_PASSWORD }}
ROOM_NAME=MyRoom
INVITEE1_MXID=@maestroelement2:matrix.org
INVITEE2_MXID=@maestroelement3:matrix.org
APP_ID=io.element.android.x.debug
MAESTRO_USERNAME=maestroelement
MAESTRO_PASSWORD=${{ secrets.MATRIX_MAESTRO_ACCOUNT_PASSWORD }}
MAESTRO_RECOVERY_KEY=${{ secrets.MATRIX_MAESTRO_ACCOUNT_RECOVERY_KEY }}
MAESTRO_ROOM_NAME=MyRoom
MAESTRO_INVITEE1_MXID=@maestroelement2:matrix.org
MAESTRO_INVITEE2_MXID=@maestroelement3:matrix.org
MAESTRO_APP_ID=io.element.android.x.debug
13 changes: 7 additions & 6 deletions .maestro/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,13 @@ From root dir of the project

```shell
maestro test \
-e APP_ID=io.element.android.x.debug \
-e USERNAME=user1 \
-e PASSWORD=123 \
-e ROOM_NAME="MyRoom" \
-e INVITEE1_MXID=user2 \
-e INVITEE2_MXID=user3 \
-e MAESTRO_APP_ID=io.element.android.x.debug \
-e MAESTRO_USERNAME=user1 \
-e MAESTRO_PASSWORD=123 \
-e MAESTRO_RECOVERY_KEY=ABC \
-e MAESTRO_ROOM_NAME="MyRoom" \
-e MAESTRO_INVITEE1_MXID=user2 \
-e MAESTRO_INVITEE2_MXID=user3 \
.maestro/allTests.yaml
```

Expand Down
2 changes: 1 addition & 1 deletion .maestro/allTests.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
## Check that all env variables required in the whole test suite are declared (to fail faster)
- runScript: ./scripts/checkEnv.js
Expand Down
13 changes: 7 additions & 6 deletions .maestro/scripts/checkEnv.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// This array contains all the required environment variable. When adding a variable, add it here also.
// If a variable is missing, an error will occur.

if (APP_ID == null) throw "Fatal: missing env variable APP_ID"
if (USERNAME == null) throw "Fatal: missing env variable USERNAME"
if (PASSWORD == null) throw "Fatal: missing env variable PASSWORD"
if (ROOM_NAME == null) throw "Fatal: missing env variable ROOM_NAME"
if (INVITEE1_MXID == null) throw "Fatal: missing env variable INVITEE1_MXID"
if (INVITEE2_MXID == null) throw "Fatal: missing env variable INVITEE2_MXID"
if (MAESTRO_APP_ID == null) throw "Fatal: missing env variable MAESTRO_APP_ID"
if (MAESTRO_USERNAME == null) throw "Fatal: missing env variable MAESTRO_USERNAME"
if (MAESTRO_PASSWORD == null) throw "Fatal: missing env variable MAESTRO_PASSWORD"
if (MAESTRO_RECOVERY_KEY == null) throw "Fatal: missing env variable MAESTRO_RECOVERY_KEY"
if (MAESTRO_ROOM_NAME == null) throw "Fatal: missing env variable MAESTRO_ROOM_NAME"
if (MAESTRO_INVITEE1_MXID == null) throw "Fatal: missing env variable MAESTRO_INVITEE1_MXID"
if (MAESTRO_INVITEE2_MXID == null) throw "Fatal: missing env variable MAESTRO_INVITEE2_MXID"
2 changes: 1 addition & 1 deletion .maestro/tests/account/changeServer.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- tapOn:
id: "login-change_server"
Expand Down
7 changes: 4 additions & 3 deletions .maestro/tests/account/login.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- tapOn: "Continue"
- runFlow: ../assertions/assertLoginDisplayed.yaml
Expand All @@ -9,7 +9,7 @@ appId: ${APP_ID}
id: "login-continue"
- tapOn:
id: "login-email_username"
- inputText: ${USERNAME}
- inputText: ${MAESTRO_USERNAME}
- pressKey: Enter
- tapOn:
id: "login-password"
Expand All @@ -20,11 +20,12 @@ appId: ${APP_ID}
- tapOn:
id: "login-password"
- eraseText: 20
- inputText: ${PASSWORD}
- inputText: ${MAESTRO_PASSWORD}
- pressKey: Enter
- tapOn: "Continue"
- runFlow: ../assertions/assertWelcomeScreenDisplayed.yaml
- tapOn: "Continue"
- runFlow: ../assertions/assertAnalyticsDisplayed.yaml
- tapOn: "Not now"
- runFlow: ../assertions/assertHomeDisplayed.yaml
- runFlow: ./verifySession.yaml
2 changes: 1 addition & 1 deletion .maestro/tests/account/logout.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- tapOn:
id: "home_screen-settings"
Expand Down
11 changes: 11 additions & 0 deletions .maestro/tests/account/verifySession.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
appId: ${MAESTRO_APP_ID}
---
- tapOn: "Continue"
- takeScreenshot: build/maestro/150-Verify
- tapOn: "Enter recovery key"
- tapOn:
id: "verification-recovery_key"
- inputText: ${MAESTRO_RECOVERY_KEY}
- hideKeyboard
- tapOn: "Confirm"
- runFlow: ../assertions/assertHomeDisplayed.yaml
2 changes: 1 addition & 1 deletion .maestro/tests/assertions/assertAnalyticsDisplayed.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- extendedWaitUntil:
visible: "Help improve Element X dbg"
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/assertions/assertHomeDisplayed.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- extendedWaitUntil:
visible: "All Chats"
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/assertions/assertInitDisplayed.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- extendedWaitUntil:
visible: "Be in your element"
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/assertions/assertLoginDisplayed.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- extendedWaitUntil:
visible: "Change account provider"
Expand Down
4 changes: 2 additions & 2 deletions .maestro/tests/assertions/assertRoomListSynced.yaml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- extendedWaitUntil:
visible: ${ROOM_NAME}
visible: ${MAESTRO_ROOM_NAME}
timeout: 10000
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- extendedWaitUntil:
visible:
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/init.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- clearState
- launchApp:
Expand Down
7 changes: 4 additions & 3 deletions .maestro/tests/roomList/createAndDeleteDM.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
# Purpose: Test the creation and deletion of a DM room.
- tapOn: "Create a new conversation or room"
- tapOn: "Search for someone"
- inputText: ${INVITEE1_MXID}
- inputText: ${MAESTRO_INVITEE1_MXID}
- tapOn:
text: ${INVITEE1_MXID}
text: ${MAESTRO_INVITEE1_MXID}
index: 1
- takeScreenshot: build/maestro/330-createAndDeleteDM
- tapOn: "maestroelement2"
- scroll
- tapOn: "Leave conversation"
- tapOn: "Leave"
10 changes: 5 additions & 5 deletions .maestro/tests/roomList/createAndDeleteRoom.yaml
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
# Purpose: Test the creation and deletion of a room
- tapOn: "Create a new conversation or room"
- tapOn: "New room"
- tapOn: "Search for someone"
- inputText: ${INVITEE1_MXID}
- inputText: ${MAESTRO_INVITEE1_MXID}
- tapOn:
text: ${INVITEE1_MXID}
text: ${MAESTRO_INVITEE1_MXID}
index: 1
- tapOn: "Next"
- tapOn: "e.g. your project name"
Expand All @@ -19,9 +19,9 @@ appId: ${APP_ID}
- tapOn: "Invite people"
# assert there's 1 member and 1 invitee
- tapOn: "Search for someone"
- inputText: ${INVITEE2_MXID}
- inputText: ${MAESTRO_INVITEE2_MXID}
- tapOn:
text: ${INVITEE2_MXID}
text: ${MAESTRO_INVITEE2_MXID}
index: 1
- tapOn: "Invite"
- tapOn: "Back"
Expand Down
6 changes: 3 additions & 3 deletions .maestro/tests/roomList/roomContextMenu.yaml
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
# Purpose: Test the context menu of a room in the room list
- longPressOn: ${ROOM_NAME}
- longPressOn: ${MAESTRO_ROOM_NAME}
- takeScreenshot: build/maestro/310-RoomList-ContextMenu
- tapOn:
text: "Settings"
index: 0
- tapOn: "Back"
- longPressOn: ${ROOM_NAME}
- longPressOn: ${MAESTRO_ROOM_NAME}
- tapOn:
text: "Leave room"
index: 0
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/roomList/roomList.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- runFlow: searchRoomList.yaml
- takeScreenshot: build/maestro/300-RoomList
Expand Down
6 changes: 3 additions & 3 deletions .maestro/tests/roomList/searchRoomList.yaml
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- runFlow: ../assertions/assertRoomListSynced.yaml
- tapOn: "search"
- inputText: ${ROOM_NAME.substring(0, 3)}
- inputText: ${MAESTRO_ROOM_NAME.substring(0, 3)}
- takeScreenshot: build/maestro/400-SearchRoom
- tapOn: ${ROOM_NAME}
- tapOn: ${MAESTRO_ROOM_NAME}
# Back from timeline
- back
- assertVisible: "MyR"
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/roomList/timeline/messages/location.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- takeScreenshot: build/maestro/520-Timeline
- tapOn: "Add attachment"
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/roomList/timeline/messages/poll.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- takeScreenshot: build/maestro/530-Timeline
- tapOn: "Add attachment"
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/roomList/timeline/messages/text.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- takeScreenshot: build/maestro/510-Timeline
- tapOn:
Expand Down
4 changes: 2 additions & 2 deletions .maestro/tests/roomList/timeline/timeline.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
# This is the name of one room
- tapOn: ${ROOM_NAME}
- tapOn: ${MAESTRO_ROOM_NAME}
- takeScreenshot: build/maestro/500-Timeline
- runFlow: messages/text.yaml
- runFlow: messages/location.yaml
Expand Down
2 changes: 1 addition & 1 deletion .maestro/tests/settings/settings.yaml
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
appId: ${APP_ID}
appId: ${MAESTRO_APP_ID}
---
- tapOn:
id: "home_screen-settings"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -338,6 +338,10 @@ class LoggedInFlowNode @AssistedInject constructor(
)
)
}

override fun onDone() {
backstack.pop()
}
}
verifySessionEntryPoint
.nodeBuilder(this, buildContext)
Expand Down
1 change: 1 addition & 0 deletions features/securebackup/impl/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ dependencies {
implementation(projects.libraries.matrixui)
implementation(projects.libraries.designsystem)
implementation(projects.libraries.uiStrings)
implementation(projects.libraries.testtags)
api(libs.statemachine)
api(projects.features.securebackup.api)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ import io.element.android.libraries.designsystem.theme.components.Icon
import io.element.android.libraries.designsystem.theme.components.OutlinedTextField
import io.element.android.libraries.designsystem.theme.components.Text
import io.element.android.libraries.designsystem.theme.components.autofill
import io.element.android.libraries.testtags.TestTags
import io.element.android.libraries.testtags.testTag
import io.element.android.libraries.ui.strings.CommonStrings

@Composable
Expand Down Expand Up @@ -169,6 +171,7 @@ private fun RecoveryKeyFormContent(
OutlinedTextField(
modifier = Modifier
.fillMaxWidth()
.testTag(TestTags.recoveryKey)
.autofill(
autofillTypes = listOf(AutofillType.Password),
onFill = { onChange(it) },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,6 @@ interface VerifySessionEntryPoint : FeatureEntryPoint {

interface Callback : Plugin {
fun onEnterRecoveryKey()
fun onDone()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,20 @@ class VerifySelfSessionNode @AssistedInject constructor(
}
}

private fun onDone() {
plugins<VerifySessionEntryPoint.Callback>().forEach {
it.onDone()
}
}

@Composable
override fun View(modifier: Modifier) {
val state = presenter.present()
VerifySelfSessionView(
state = state,
modifier = modifier,
onEnterRecoveryKey = { onEnterRecoveryKey() },
goBack = { navigateUp() }
onEnterRecoveryKey = ::onEnterRecoveryKey,
goBack = ::onDone,
)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ class RustMatrixClient(
syncService = rustSyncService,
sessionCoroutineScope = sessionCoroutineScope,
dispatchers = dispatchers,
).apply { start() }
)
private val sessionDirectoryNameProvider = SessionDirectoryNameProvider()

private val isLoggingOut = AtomicBoolean(false)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright (c) 2024 New Vector Ltd
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package io.element.android.libraries.matrix.impl.encryption

import io.element.android.libraries.matrix.api.encryption.BackupState
import io.element.android.libraries.matrix.api.encryption.RecoveryState
import io.element.android.libraries.matrix.impl.util.mxCallbackFlow
import kotlinx.coroutines.flow.Flow
import org.matrix.rustcomponents.sdk.BackupStateListener
import org.matrix.rustcomponents.sdk.EncryptionInterface
import org.matrix.rustcomponents.sdk.RecoveryStateListener
import org.matrix.rustcomponents.sdk.BackupState as RustBackupState
import org.matrix.rustcomponents.sdk.RecoveryState as RustRecoveryState

internal fun EncryptionInterface.backupStateFlow(): Flow<BackupState> = mxCallbackFlow {
val backupStateMapper = BackupStateMapper()
trySend(backupStateMapper.map(backupState()))
val listener = object : BackupStateListener {
override fun onUpdate(status: RustBackupState) {
trySend(backupStateMapper.map(status))
}
}
backupStateListener(listener)
}

internal fun EncryptionInterface.recoveryStateFlow(): Flow<RecoveryState> = mxCallbackFlow {
val recoveryStateMapper = RecoveryStateMapper()
trySend(recoveryStateMapper.map(recoveryState()))
val listener = object : RecoveryStateListener {
override fun onUpdate(status: RustRecoveryState) {
trySend(recoveryStateMapper.map(status))
}
}
recoveryStateListener(listener)
}
Loading
Loading