Browse Source

Merge pull request #28 from vector-im/feature/bma/uiTests

UI tests
feature/jme/update_rust_sdk
Benoit Marty 2 years ago committed by GitHub
parent
commit
321701c5b8
  1. 1
      .gitattributes
  2. 9
      .github/workflows/tests.yml
  3. 15
      .github/workflows/validate-lfs.yml
  4. 23
      app/build.gradle.kts
  5. 7
      app/src/main/kotlin/io/element/android/x/root/RootView.kt
  6. 45
      docs/screenshot_testing.md
  7. 9
      features/login/src/main/kotlin/io/element/android/x/features/login/changeserver/ChangeServerView.kt
  8. 13
      features/login/src/main/kotlin/io/element/android/x/features/login/root/LoginRootScreen.kt
  9. 5
      features/logout/src/main/kotlin/io/element/android/x/features/logout/LogoutPreferenceScreen.kt
  10. 2
      features/messages/src/main/kotlin/io/element/android/x/features/messages/textcomposer/MessageComposerView.kt
  11. 2
      features/messages/src/main/kotlin/io/element/android/x/features/messages/timeline/TimelineView.kt
  12. 9
      features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/bugreport/BugReportView.kt
  13. 9
      features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/crash/ui/CrashDetectionScreen.kt
  14. 5
      features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/detection/RageshakeDetectionView.kt
  15. 8
      features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/preferences/RageshakePreferencesView.kt
  16. 36
      features/roomlist/src/main/kotlin/io/element/android/x/features/roomlist/RoomListView.kt
  17. 4
      gradle/libs.versions.toml
  18. 4
      libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/avatar/Avatar.kt
  19. 2
      libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceCategory.kt
  20. 2
      libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceScreen.kt
  21. 2
      libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceSlide.kt
  22. 2
      libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceSwitch.kt
  23. 2
      libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceText.kt
  24. 33
      libraries/matrixui/src/main/kotlin/io/element/android/x/matrix/ui/components/MatrixUserHeader.kt
  25. 17
      libraries/matrixui/src/main/kotlin/io/element/android/x/matrix/ui/components/MatrixUserRow.kt
  26. 4
      libraries/textcomposer/src/main/kotlin/io/element/android/x/textcomposer/TextComposer.kt
  27. 19
      plugins/src/main/kotlin/extension/DependencyHandleScope.kt
  28. 8
      plugins/src/main/kotlin/io.element.android-compose-library.gradle.kts
  29. 8
      plugins/src/main/kotlin/io.element.android-library.gradle.kts
  30. 1
      settings.gradle.kts
  31. 1
      tests/uitests/.gitignore
  32. 44
      tests/uitests/build.gradle.kts
  33. 0
      tests/uitests/consumer-rules.pro
  34. 21
      tests/uitests/proguard-rules.pro
  35. 18
      tests/uitests/src/main/AndroidManifest.xml
  36. 4
      tests/uitests/src/main/kotlin/io/element/android/x/tests/uitests/ElementXShowkaseRootModule.kt
  37. 66
      tests/uitests/src/main/kotlin/io/element/android/x/tests/uitests/ShowkaseButton.kt
  38. 24
      tests/uitests/src/main/kotlin/io/element/android/x/tests/uitests/ShowkaseNavigation.kt
  39. 26
      tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/BaseDeviceConfig.kt
  40. 42
      tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/ColorTestPreview.kt
  41. 28
      tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/ComponentTestPreview.kt
  42. 121
      tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/ScreenshotTest.kt
  43. 24
      tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/TestPreview.kt
  44. 48
      tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/TypographyTestPreview.kt
  45. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_DarkGrey,NEXUS_5,1,dark,en].png
  46. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_DarkGrey,NEXUS_5,1,light,en].png
  47. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_LightGrey,NEXUS_5,1,dark,en].png
  48. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_LightGrey,NEXUS_5,1,light,en].png
  49. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Body Large,NEXUS_5,1,dark,en].png
  50. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Body Large,NEXUS_5,1,light,en].png
  51. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Headline Small,NEXUS_5,1,dark,en].png
  52. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Headline Small,NEXUS_5,1,light,en].png
  53. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.avatar_null_DefaultGroup_InitialsAvatarPreview_,NEXUS_5,1,dark,en].png
  54. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.avatar_null_DefaultGroup_InitialsAvatarPreview_,NEXUS_5,1,light,en].png
  55. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ConfirmationDialogPreview_,NEXUS_5,1,dark,en].png
  56. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ConfirmationDialogPreview_,NEXUS_5,1,light,en].png
  57. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ErrorDialogPreview_,NEXUS_5,1,dark,en].png
  58. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ErrorDialogPreview_,NEXUS_5,1,light,en].png
  59. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceCategoryPreview_,NEXUS_5,1,dark,en].png
  60. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceCategoryPreview_,NEXUS_5,1,light,en].png
  61. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceScreenPreview_,NEXUS_5,1,dark,en].png
  62. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceScreenPreview_,NEXUS_5,1,light,en].png
  63. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSlidePreview_,NEXUS_5,1,dark,en].png
  64. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSlidePreview_,NEXUS_5,1,light,en].png
  65. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSwitchPreview_,NEXUS_5,1,dark,en].png
  66. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSwitchPreview_,NEXUS_5,1,light,en].png
  67. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceTextPreview_,NEXUS_5,1,dark,en].png
  68. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceTextPreview_,NEXUS_5,1,light,en].png
  69. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_LabelledCheckboxPreview_,NEXUS_5,1,dark,en].png
  70. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_LabelledCheckboxPreview_,NEXUS_5,1,light,en].png
  71. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_ProgressDialogPreview_,NEXUS_5,1,dark,en].png
  72. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_ProgressDialogPreview_,NEXUS_5,1,light,en].png
  73. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.changeserver_null_DefaultGroup_ChangeServerContentPreview_,NEXUS_5,1,dark,en].png
  74. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.changeserver_null_DefaultGroup_ChangeServerContentPreview_,NEXUS_5,1,light,en].png
  75. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.root_null_DefaultGroup_LoginContentPreview_,NEXUS_5,1,dark,en].png
  76. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.root_null_DefaultGroup_LoginContentPreview_,NEXUS_5,1,light,en].png
  77. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.logout_null_DefaultGroup_LogoutContentPreview_,NEXUS_5,1,dark,en].png
  78. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.logout_null_DefaultGroup_LogoutContentPreview_,NEXUS_5,1,light,en].png
  79. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__0,NEXUS_5,1,dark,en].png
  80. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__0,NEXUS_5,1,light,en].png
  81. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__1,NEXUS_5,1,dark,en].png
  82. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__1,NEXUS_5,1,light,en].png
  83. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__2,NEXUS_5,1,dark,en].png
  84. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__2,NEXUS_5,1,light,en].png
  85. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__3,NEXUS_5,1,dark,en].png
  86. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__3,NEXUS_5,1,light,en].png
  87. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__4,NEXUS_5,1,dark,en].png
  88. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__4,NEXUS_5,1,light,en].png
  89. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__5,NEXUS_5,1,dark,en].png
  90. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__5,NEXUS_5,1,light,en].png
  91. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.preferences.root_null_DefaultGroup_PreferencesContentPreview_,NEXUS_5,1,dark,en].png
  92. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.preferences.root_null_DefaultGroup_PreferencesContentPreview_,NEXUS_5,1,light,en].png
  93. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.bugreport_null_DefaultGroup_BugReportContentPreview_,NEXUS_5,1,dark,en].png
  94. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.bugreport_null_DefaultGroup_BugReportContentPreview_,NEXUS_5,1,light,en].png
  95. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.crash.ui_null_DefaultGroup_CrashDetectionContentPreview_,NEXUS_5,1,dark,en].png
  96. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.crash.ui_null_DefaultGroup_CrashDetectionContentPreview_,NEXUS_5,1,light,en].png
  97. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.detection_null_DefaultGroup_RageshakeDialogContentPreview_,NEXUS_5,1,dark,en].png
  98. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.detection_null_DefaultGroup_RageshakeDialogContentPreview_,NEXUS_5,1,light,en].png
  99. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.preferences_null_DefaultGroup_RageshakePreferenceNotSupportedPreview_,NEXUS_5,1,dark,en].png
  100. BIN
      tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.preferences_null_DefaultGroup_RageshakePreferenceNotSupportedPreview_,NEXUS_5,1,light,en].png
  101. Some files were not shown because too many files have changed in this diff Show More

1
.gitattributes vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
**/snapshots/**/*.png filter=lfs diff=lfs merge=lfs -text

9
.github/workflows/tests.yml

@ -23,3 +23,12 @@ jobs: @@ -23,3 +23,12 @@ jobs:
- uses: actions/checkout@v3
- name: Run tests
run: ./gradlew test $CI_GRADLE_ARG_PROPERTIES
- name: Archive test results on error
if: failure()
uses: actions/upload-artifact@v3
with:
name: screenshot-results
path: |
**/out/failures/
**/build/reports/tests/*UnitTest/

15
.github/workflows/validate-lfs.yml

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
name: Validate Git LFS
on: [pull_request]
jobs:
build:
runs-on: ubuntu-latest
name: Validate
steps:
- uses: actions/checkout@v3
with:
lfs: 'true'
- run: |
./tools/git/validate_lfs.sh

23
app/build.gradle.kts

@ -16,6 +16,9 @@ @@ -16,6 +16,9 @@
* limitations under the License.
*/
import extension.allFeatures
import extension.allLibraries
// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
@ -125,6 +128,7 @@ android { @@ -125,6 +128,7 @@ android {
}
}
// Waiting for https://github.com/google/ksp/issues/37
applicationVariants.all {
kotlin.sourceSets {
getByName(name) {
@ -156,19 +160,9 @@ knit { @@ -156,19 +160,9 @@ knit {
}
dependencies {
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:matrix"))
implementation(project(":libraries:matrixui"))
implementation(project(":libraries:core"))
implementation(project(":libraries:architecture"))
implementation(project(":features:onboarding"))
implementation(project(":features:login"))
implementation(project(":features:logout"))
implementation(project(":features:roomlist"))
implementation(project(":features:messages"))
implementation(project(":features:rageshake"))
implementation(project(":features:preferences"))
implementation(project(":libraries:di"))
allLibraries()
allFeatures()
implementation(project(":tests:uitests"))
implementation(project(":anvilannotations"))
anvil(project(":anvilcodegen"))
@ -184,7 +178,4 @@ dependencies { @@ -184,7 +178,4 @@ dependencies {
implementation(libs.dagger)
kapt(libs.dagger.compiler)
implementation(libs.showkase)
ksp(libs.showkase.processor)
}

7
app/src/main/kotlin/io/element/android/x/root/RootView.kt

@ -16,6 +16,7 @@ @@ -16,6 +16,7 @@
package io.element.android.x.root
import android.app.Activity
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.BoxScope
import androidx.compose.foundation.layout.fillMaxSize
@ -23,14 +24,12 @@ import androidx.compose.runtime.Composable @@ -23,14 +24,12 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat
import com.airbnb.android.showkase.models.Showkase
import io.element.android.x.component.ShowkaseButton
import io.element.android.x.features.rageshake.crash.ui.CrashDetectionEvents
import io.element.android.x.features.rageshake.crash.ui.CrashDetectionView
import io.element.android.x.features.rageshake.detection.RageshakeDetectionEvents
import io.element.android.x.features.rageshake.detection.RageshakeDetectionView
import io.element.android.x.getBrowserIntent
import io.element.android.x.tests.uitests.openShowkase
@Composable
fun RootView(
@ -57,7 +56,7 @@ fun RootView( @@ -57,7 +56,7 @@ fun RootView(
ShowkaseButton(
isVisible = state.isShowkaseButtonVisible,
onCloseClicked = { eventSink(RootEvents.HideShowkaseButton) },
onClick = { ContextCompat.startActivity(context, Showkase.getBrowserIntent(context), null) }
onClick = { openShowkase(context as Activity) }
)
RageshakeDetectionView(
state = state.rageshakeDetectionState,

45
docs/screenshot_testing.md

@ -0,0 +1,45 @@ @@ -0,0 +1,45 @@
# Screenshot testing
<!--- TOC -->
* [Overview](#overview)
* [Setup](#setup)
* [Recording](#recording)
* [Verifying](#verifying)
* [Contributing](#contributing)
<!--- END -->
## Overview
- Screenshot tests are tests which record the content of a rendered screen and verify subsequent runs to check if the screen renders differently.
- ElementX uses [Paparazzi](https://github.com/cashapp/paparazzi) to render, record and verify Composable. All Composable Preview will be use to make screenshot test, thanks to the usage of [Showkase](https://github.com/airbnb/Showkase).
- The screenshot verification occurs on every pull request as part of the `tests.yml` workflow.
## Setup
- Install Git LFS through your package manager of choice (`brew install git-lfs` | `yay -S git-lfs`).
- Install the Git LFS hooks into the project.
```bash
# with element-android as the current working directory
git lfs install --local
```
- If installed correctly, `git push` and `git pull` will now include LFS content.
## Recording
- `./gradlew recordPaparazziDebug`
- Paparazzi will generate images in `:tests:uitests/src/test/snapshots`, which will need to be committed to the repository using Git LFS.
## Verifying
- `./gradlew verifyPaparazziDebug`
- In the case of failure, Paparazzi will generate images in `:tests:uitests/out/failure`. The images will show the expected and actual screenshots along with a delta of the two images.
## Contributing
- Creating Previewable Composable will automatically creates new screenshot tests.
- After creating the new test, record and commit the newly rendered screens.
- `./tools/git/validate_lfs.sh` can be run to ensure everything is working correctly with Git LFS, the CI also runs this check.

9
features/login/src/main/kotlin/io/element/android/x/features/login/changeserver/ChangeServerView.kt

@ -54,7 +54,6 @@ import androidx.compose.ui.unit.dp @@ -54,7 +54,6 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.x.architecture.Async
import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.VectorIcon
import io.element.android.x.features.login.R
import io.element.android.x.features.login.error.changeServerError
@ -183,9 +182,7 @@ fun ChangeServerView( @@ -183,9 +182,7 @@ fun ChangeServerView(
@Composable
@Preview
fun ChangeServerContentPreview() {
ElementXTheme {
ChangeServerView(
state = ChangeServerState(homeserver = "matrix.org"),
)
}
ChangeServerView(
state = ChangeServerState(homeserver = "matrix.org"),
)
}

13
features/login/src/main/kotlin/io/element/android/x/features/login/root/LoginRootScreen.kt

@ -59,7 +59,6 @@ import androidx.compose.ui.tooling.preview.Preview @@ -59,7 +59,6 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.features.login.error.loginError
import io.element.android.x.matrix.core.SessionId
import io.element.android.x.ui.strings.R as StringR
@ -224,11 +223,9 @@ fun LoginRootScreen( @@ -224,11 +223,9 @@ fun LoginRootScreen(
@Composable
@Preview
fun LoginContentPreview() {
ElementXTheme(darkTheme = false) {
LoginRootScreen(
state = LoginRootState(
homeserver = "matrix.org",
),
)
}
LoginRootScreen(
state = LoginRootState(
homeserver = "matrix.org",
),
)
}

5
features/logout/src/main/kotlin/io/element/android/x/features/logout/LogoutPreferenceScreen.kt

@ -25,7 +25,6 @@ import androidx.compose.runtime.remember @@ -25,7 +25,6 @@ import androidx.compose.runtime.remember
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.x.architecture.Async
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.ProgressDialog
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.x.designsystem.components.preferences.PreferenceCategory
@ -92,7 +91,5 @@ fun LogoutPreferenceContent( @@ -92,7 +91,5 @@ fun LogoutPreferenceContent(
@Composable
@Preview
fun LogoutContentPreview() {
ElementXTheme(darkTheme = false) {
LogoutPreferenceView(LogoutPreferenceState())
}
LogoutPreferenceView(LogoutPreferenceState())
}

2
features/messages/src/main/kotlin/io/element/android/x/features/messages/textcomposer/MessageComposerView.kt

@ -18,6 +18,7 @@ package io.element.android.x.features.messages.textcomposer @@ -18,6 +18,7 @@ package io.element.android.x.features.messages.textcomposer
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import io.element.android.x.designsystem.LocalIsDarkTheme
import io.element.android.x.textcomposer.TextComposer
@Composable
@ -50,6 +51,7 @@ fun MessageComposerView( @@ -50,6 +51,7 @@ fun MessageComposerView(
onComposerTextChange = ::onComposerTextChange,
composerCanSendMessage = state.isSendButtonVisible,
composerText = state.text?.charSequence?.toString(),
isInDarkMode = LocalIsDarkTheme.current,
modifier = modifier
)
}

2
features/messages/src/main/kotlin/io/element/android/x/features/messages/timeline/TimelineView.kt

@ -356,7 +356,7 @@ class MessagesItemGroupPositionToMessagesTimelineItemContentProvider : @@ -356,7 +356,7 @@ class MessagesItemGroupPositionToMessagesTimelineItemContentProvider :
)
@Suppress("PreviewPublic")
@Preview(showBackground = true)
@Preview
@Composable
fun TimelineItemsPreview(
@PreviewParameter(MessagesTimelineItemContentProvider::class)

9
features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/bugreport/BugReportView.kt

@ -53,7 +53,6 @@ import coil.request.ImageRequest @@ -53,7 +53,6 @@ import coil.request.ImageRequest
import io.element.android.x.architecture.Async
import io.element.android.x.core.compose.LogCompositions
import io.element.android.x.core.compose.textFieldState
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.LabelledCheckbox
import io.element.android.x.designsystem.components.dialogs.ErrorDialog
import io.element.android.x.ui.strings.R as StringR
@ -213,9 +212,7 @@ fun BugReportView( @@ -213,9 +212,7 @@ fun BugReportView(
@Composable
@Preview
fun BugReportContentPreview() {
ElementXTheme(darkTheme = false) {
BugReportView(
state = BugReportState(),
)
}
BugReportView(
state = BugReportState(),
)
}

9
features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/crash/ui/CrashDetectionScreen.kt

@ -20,7 +20,6 @@ import androidx.compose.runtime.Composable @@ -20,7 +20,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import io.element.android.x.core.compose.LogCompositions
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.x.ui.strings.R as StringR
@ -66,9 +65,7 @@ fun CrashDetectionContent( @@ -66,9 +65,7 @@ fun CrashDetectionContent(
@Preview
@Composable
fun CrashDetectionContentPreview() {
ElementXTheme {
CrashDetectionContent(
state = CrashDetectionState()
)
}
CrashDetectionContent(
state = CrashDetectionState()
)
}

5
features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/detection/RageshakeDetectionView.kt

@ -28,7 +28,6 @@ import io.element.android.x.core.compose.OnLifecycleEvent @@ -28,7 +28,6 @@ import io.element.android.x.core.compose.OnLifecycleEvent
import io.element.android.x.core.hardware.vibrate
import io.element.android.x.core.screenshot.ImageResult
import io.element.android.x.core.screenshot.screenshot
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.dialogs.ConfirmationDialog
import io.element.android.x.ui.strings.R as StringR
@ -98,7 +97,5 @@ fun RageshakeDialogContent( @@ -98,7 +97,5 @@ fun RageshakeDialogContent(
@Preview
@Composable
fun RageshakeDialogContentPreview() {
ElementXTheme {
RageshakeDialogContent()
}
RageshakeDialogContent()
}

8
features/rageshake/src/main/kotlin/io/element/android/x/features/rageshake/preferences/RageshakePreferencesView.kt

@ -75,6 +75,12 @@ fun RageshakePreferencesView( @@ -75,6 +75,12 @@ fun RageshakePreferencesView(
@Composable
@Preview
fun RageshakePreferencesPreview() {
fun RageshakePreferencesViewPreview() {
RageshakePreferencesView(RageshakePreferencesState(isEnabled = true, isSupported = true, sensitivity = 0.5f))
}
@Composable
@Preview
fun RageshakePreferenceNotSupportedPreview() {
RageshakePreferencesView(RageshakePreferencesState(isEnabled = true, isSupported = false, sensitivity = 0.5f))
}

36
features/roomlist/src/main/kotlin/io/element/android/x/features/roomlist/RoomListView.kt

@ -37,7 +37,6 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll @@ -37,7 +37,6 @@ import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Velocity
import io.element.android.x.core.compose.LogCompositions
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.features.roomlist.components.RoomListTopBar
import io.element.android.x.features.roomlist.components.RoomSummaryRow
@ -150,30 +149,13 @@ private fun RoomListRoomSummary.contentType() = isPlaceholder @@ -150,30 +149,13 @@ private fun RoomListRoomSummary.contentType() = isPlaceholder
@Preview
@Composable
fun PreviewableRoomListView() {
ElementXTheme(darkTheme = false) {
RoomListView(
roomSummaries = stubbedRoomSummaries(),
matrixUser = MatrixUser(id = UserId("@id"), username = "User#1", avatarData = AvatarData("U")),
onRoomClicked = {},
filter = "filter",
onFilterChanged = {},
onScrollOver = {}
)
}
}
@Preview
@Composable
fun PreviewableDarkRoomListView() {
ElementXTheme(darkTheme = true) {
RoomListView(
roomSummaries = stubbedRoomSummaries(),
matrixUser = MatrixUser(id = UserId("@id"), username = "User#1", avatarData = AvatarData("U")),
onRoomClicked = {},
filter = "filter",
onFilterChanged = {},
onScrollOver = {}
)
}
fun RoomListViewPreview() {
RoomListView(
roomSummaries = stubbedRoomSummaries(),
matrixUser = MatrixUser(id = UserId("@id"), username = "User#1", avatarData = AvatarData("U")),
onRoomClicked = {},
filter = "filter",
onFilterChanged = {},
onScrollOver = {}
)
}

4
gradle/libs.versions.toml

@ -38,6 +38,8 @@ test_junitext = "1.1.3" @@ -38,6 +38,8 @@ test_junitext = "1.1.3"
test_barista = "4.2.0"
test_hamcrest = "2.2"
test_orchestrator = "1.4.1"
test_paparazzi = "1.2.0"
test_parameter_injector = "1.8"
#other
coil = "2.2.2"
@ -110,6 +112,7 @@ test_mockk = { module = "io.mockk:mockk", version.ref = "test_mockk" } @@ -110,6 +112,7 @@ test_mockk = { module = "io.mockk:mockk", version.ref = "test_mockk" }
test_barista = { module = "com.adevinta.android:barista", version.ref = "test_barista" }
test_hamcrest = { module = "org.hamcrest:hamcrest", version.ref = "test_hamcrest" }
test_orchestrator = { module = "androidx.test:orchestrator", version.ref = "test_orchestrator" }
test_parameter_injector = { module = "com.google.testparameterinjector:test-parameter-injector", version.ref = "test_parameter_injector" }
# Others
coil = { module = "io.coil-kt:coil", version.ref = "coil" }
@ -148,3 +151,4 @@ dependencygraph = { id = "com.savvasdalkitsis.module-dependency-graph", version. @@ -148,3 +151,4 @@ dependencygraph = { id = "com.savvasdalkitsis.module-dependency-graph", version.
dependencycheck = { id = "org.owasp.dependencycheck", version.ref = "dependencycheck" }
stem = { id = "com.likethesalad.stem", version.ref = "stem" }
stemlibrary = { id = "com.likethesalad.stem-library", version.ref = "stem" }
paparazzi = { id = "app.cash.paparazzi", version.ref = "test_paparazzi" }

4
libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/avatar/Avatar.kt

@ -97,6 +97,6 @@ private fun InitialsAvatar( @@ -97,6 +97,6 @@ private fun InitialsAvatar(
@Preview
@Composable
fun InitialsAvatar() {
InitialsAvatar(AvatarData("A"))
fun InitialsAvatarPreview() {
Avatar(AvatarData(name = "A"))
}

2
libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceCategory.kt

@ -53,7 +53,7 @@ fun PreferenceCategory( @@ -53,7 +53,7 @@ fun PreferenceCategory(
}
@Composable
@Preview(showBackground = false)
@Preview
fun PreferenceCategoryPreview() {
PreferenceCategory(
title = "Category title",

2
libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceScreen.kt

@ -111,7 +111,7 @@ fun PreferenceTopAppBar( @@ -111,7 +111,7 @@ fun PreferenceTopAppBar(
}
@Composable
@Preview(showBackground = false)
@Preview
fun PreferenceScreenPreview() {
PreferenceView(
title = "Preference screen"

2
libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceSlide.kt

@ -85,7 +85,7 @@ fun PreferenceSlide( @@ -85,7 +85,7 @@ fun PreferenceSlide(
}
@Composable
@Preview(showBackground = false)
@Preview
fun PreferenceSlidePreview() {
PreferenceSlide(
title = "Slide",

2
libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceSwitch.kt

@ -76,7 +76,7 @@ fun PreferenceSwitch( @@ -76,7 +76,7 @@ fun PreferenceSwitch(
}
@Composable
@Preview(showBackground = false)
@Preview
fun PreferenceSwitchPreview() {
PreferenceSwitch(
title = "Switch",

2
libraries/designsystem/src/main/kotlin/io/element/android/x/designsystem/components/preferences/PreferenceText.kt

@ -64,7 +64,7 @@ fun PreferenceText( @@ -64,7 +64,7 @@ fun PreferenceText(
}
@Composable
@Preview(showBackground = false)
@Preview
fun PreferenceTextPreview() {
PreferenceText(
title = "Title",

33
libraries/matrixui/src/main/kotlin/io/element/android/x/matrix/ui/components/MatrixUserHeader.kt

@ -33,7 +33,6 @@ import androidx.compose.ui.text.style.TextOverflow @@ -33,7 +33,6 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.avatar.Avatar
import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.designsystem.components.avatar.AvatarSize
@ -84,29 +83,25 @@ fun MatrixUserHeader( @@ -84,29 +83,25 @@ fun MatrixUserHeader(
@Preview
@Composable
fun MatrixUserHeaderPreview() {
ElementXTheme {
MatrixUserHeader(
MatrixUser(
id = UserId("@alice:server.org"),
username = "Alice",
avatarUrl = null,
avatarData = AvatarData("Alice")
)
MatrixUserHeader(
MatrixUser(
id = UserId("@alice:server.org"),
username = "Alice",
avatarUrl = null,
avatarData = AvatarData("Alice")
)
}
)
}
@Preview
@Composable
fun MatrixUserHeaderNoUsernamePreview() {
ElementXTheme {
MatrixUserHeader(
MatrixUser(
id = UserId("@alice:server.org"),
username = null,
avatarUrl = null,
avatarData = AvatarData("Alice")
)
MatrixUserHeader(
MatrixUser(
id = UserId("@alice:server.org"),
username = null,
avatarUrl = null,
avatarData = AvatarData("Alice")
)
}
)
}

17
libraries/matrixui/src/main/kotlin/io/element/android/x/matrix/ui/components/MatrixUserRow.kt

@ -33,7 +33,6 @@ import androidx.compose.ui.text.style.TextOverflow @@ -33,7 +33,6 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import io.element.android.x.designsystem.ElementXTheme
import io.element.android.x.designsystem.components.avatar.Avatar
import io.element.android.x.designsystem.components.avatar.AvatarData
import io.element.android.x.matrix.core.UserId
@ -88,14 +87,12 @@ fun MatrixUserRow( @@ -88,14 +87,12 @@ fun MatrixUserRow(
@Preview
@Composable
fun MatrixUserRowPreview() {
ElementXTheme {
MatrixUserRow(
MatrixUser(
id = UserId("@alice:server.org"),
username = "Alice",
avatarUrl = null,
avatarData = AvatarData("Alice")
)
MatrixUserRow(
MatrixUser(
id = UserId("@alice:server.org"),
username = "Alice",
avatarUrl = null,
avatarData = AvatarData("Alice")
)
}
)
}

4
libraries/textcomposer/src/main/kotlin/io/element/android/x/textcomposer/TextComposer.kt

@ -18,7 +18,6 @@ package io.element.android.x.textcomposer @@ -18,7 +18,6 @@ package io.element.android.x.textcomposer
import android.graphics.Color
import android.net.Uri
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
@ -42,6 +41,7 @@ fun TextComposer( @@ -42,6 +41,7 @@ fun TextComposer(
composerText: String?,
composerMode: MessageComposerMode,
composerCanSendMessage: Boolean,
isInDarkMode: Boolean,
modifier: Modifier = Modifier,
onSendMessage: (String) -> Unit = {},
onFullscreenToggle: () -> Unit = {},
@ -51,7 +51,6 @@ fun TextComposer( @@ -51,7 +51,6 @@ fun TextComposer(
if (LocalInspectionMode.current) {
FakeComposer(modifier)
} else {
val isInDarkMode = isSystemInDarkTheme()
AndroidView(
modifier = modifier,
factory = { context ->
@ -156,5 +155,6 @@ fun TextComposerPreview() { @@ -156,5 +155,6 @@ fun TextComposerPreview() {
onCloseSpecialMode = {},
composerCanSendMessage = true,
composerText = "Message",
isInDarkMode = true,
)
}

19
plugins/src/main/kotlin/extension/DependencyHandleScope.kt

@ -20,6 +20,7 @@ import gradle.kotlin.dsl.accessors._4b7ad2363fc1fce7c774e054dc9a9300.androidTest @@ -20,6 +20,7 @@ import gradle.kotlin.dsl.accessors._4b7ad2363fc1fce7c774e054dc9a9300.androidTest
import gradle.kotlin.dsl.accessors._4b7ad2363fc1fce7c774e054dc9a9300.debugImplementation
import gradle.kotlin.dsl.accessors._4b7ad2363fc1fce7c774e054dc9a9300.implementation
import org.gradle.kotlin.dsl.DependencyHandlerScope
import org.gradle.kotlin.dsl.project
/**
* Dependencies used by all the modules
@ -48,3 +49,21 @@ fun DependencyHandlerScope.composeDependencies() { @@ -48,3 +49,21 @@ fun DependencyHandlerScope.composeDependencies() {
implementation("org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.5")
}
fun DependencyHandlerScope.allLibraries() {
implementation(project(":libraries:designsystem"))
implementation(project(":libraries:matrix"))
implementation(project(":libraries:matrixui"))
implementation(project(":libraries:core"))
implementation(project(":libraries:architecture"))
implementation(project(":libraries:di"))
}
fun DependencyHandlerScope.allFeatures() {
implementation(project(":features:onboarding"))
implementation(project(":features:login"))
implementation(project(":features:logout"))
implementation(project(":features:roomlist"))
implementation(project(":features:messages"))
implementation(project(":features:rageshake"))
implementation(project(":features:preferences"))
}

8
plugins/src/main/kotlin/io.element.android-compose-library.gradle.kts

@ -30,6 +30,14 @@ plugins { @@ -30,6 +30,14 @@ plugins {
android {
androidConfig(project)
composeConfig()
// Waiting for https://github.com/google/ksp/issues/37
libraryVariants.all {
kotlin.sourceSets {
getByName(name) {
kotlin.srcDir("build/generated/ksp/$name/kotlin")
}
}
}
}
dependencies {

8
plugins/src/main/kotlin/io.element.android-library.gradle.kts

@ -27,6 +27,14 @@ plugins { @@ -27,6 +27,14 @@ plugins {
android {
androidConfig(project)
// Waiting for https://github.com/google/ksp/issues/37
libraryVariants.all {
kotlin.sourceSets {
getByName(name) {
kotlin.srcDir("build/generated/ksp/$name/kotlin")
}
}
}
}
dependencies {

1
settings.gradle.kts

@ -50,6 +50,7 @@ include(":features:rageshake") @@ -50,6 +50,7 @@ include(":features:rageshake")
include(":features:preferences")
include(":libraries:designsystem")
include(":libraries:di")
include(":tests:uitests")
include(":anvilannotations")
include(":anvilcodegen")
include(":libraries:architecture")

1
tests/uitests/.gitignore vendored

@ -0,0 +1 @@ @@ -0,0 +1 @@
/build

44
tests/uitests/build.gradle.kts

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
/*
* Copyright (c) 2022 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.
*/
import extension.allFeatures
import extension.allLibraries
// TODO: Remove once https://youtrack.jetbrains.com/issue/KTIJ-19369 is fixed
@Suppress("DSL_SCOPE_VIOLATION")
plugins {
id("io.element.android-compose-library")
alias(libs.plugins.ksp)
alias(libs.plugins.paparazzi)
}
android {
namespace = "io.element.android.x.tests.uitests"
}
dependencies {
testImplementation(libs.test.junit)
testImplementation(libs.test.parameter.injector)
androidTestImplementation(libs.test.junitext)
ksp(libs.showkase.processor)
kspTest(libs.showkase.processor)
implementation(libs.showkase)
ksp(libs.showkase.processor)
allLibraries()
allFeatures()
}

0
tests/uitests/consumer-rules.pro

21
tests/uitests/proguard-rules.pro vendored

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

18
tests/uitests/src/main/AndroidManifest.xml

@ -0,0 +1,18 @@ @@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
~ Copyright (c) 2022 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.
-->
<manifest/>

4
app/src/main/kotlin/io/element/android/x/ElementRootModule.kt → tests/uitests/src/main/kotlin/io/element/android/x/tests/uitests/ElementXShowkaseRootModule.kt

@ -14,10 +14,10 @@ @@ -14,10 +14,10 @@
* limitations under the License.
*/
package io.element.android.x
package io.element.android.x.tests.uitests
import com.airbnb.android.showkase.annotation.ShowkaseRoot
import com.airbnb.android.showkase.annotation.ShowkaseRootModule
@ShowkaseRoot
class ElementRootModule : ShowkaseRootModule
class ElementXShowkaseRootModule : ShowkaseRootModule

66
tests/uitests/src/main/kotlin/io/element/android/x/tests/uitests/ShowkaseButton.kt

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Button
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
@Composable
fun ShowkaseButton(
modifier: Modifier = Modifier,
onClick: () -> Unit = {},
) {
var isShowkaseButtonVisible by remember { mutableStateOf(BuildConfig.DEBUG) }
if (isShowkaseButtonVisible) {
Button(
modifier = modifier
.padding(top = 32.dp),
onClick = onClick
) {
Text(text = "Showkase Browser")
IconButton(
modifier = Modifier
.padding(start = 8.dp)
.size(16.dp),
onClick = { isShowkaseButtonVisible = false },
) {
Icon(imageVector = Icons.Filled.Close, contentDescription = "")
}
}
}
}
@Preview(group = "Buttons", name = "Showkase button")
@Composable
fun ShowkaseButtonPreview() {
ShowkaseButton()
}

24
tests/uitests/src/main/kotlin/io/element/android/x/tests/uitests/ShowkaseNavigation.kt

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import android.app.Activity
import com.airbnb.android.showkase.models.Showkase
fun openShowkase(activity: Activity) {
activity.startActivity(Showkase.getBrowserIntent(activity))
}

26
tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/BaseDeviceConfig.kt

@ -0,0 +1,26 @@ @@ -0,0 +1,26 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import app.cash.paparazzi.DeviceConfig
enum class BaseDeviceConfig(
val deviceConfig: DeviceConfig,
) {
NEXUS_5(DeviceConfig.NEXUS_5),
// PIXEL_C(DeviceConfig.PIXEL_C),
}

42
tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/ColorTestPreview.kt

@ -0,0 +1,42 @@ @@ -0,0 +1,42 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import com.airbnb.android.showkase.models.ShowkaseBrowserColor
class ColorTestPreview(
private val showkaseBrowserColor: ShowkaseBrowserColor
) : TestPreview {
@Composable
override fun Content() {
Box(
modifier = Modifier
.fillMaxWidth()
.height(250.dp)
.background(showkaseBrowserColor.color)
)
}
override fun toString(): String = "Color_${showkaseBrowserColor.colorGroup}_${showkaseBrowserColor.colorName}"
}

28
tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/ComponentTestPreview.kt

@ -0,0 +1,28 @@ @@ -0,0 +1,28 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import androidx.compose.runtime.Composable
import com.airbnb.android.showkase.models.ShowkaseBrowserComponent
class ComponentTestPreview(
private val showkaseBrowserComponent: ShowkaseBrowserComponent
) : TestPreview {
@Composable
override fun Content() = showkaseBrowserComponent.component()
override fun toString(): String = showkaseBrowserComponent.componentKey
}

121
tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/ScreenshotTest.kt

@ -0,0 +1,121 @@ @@ -0,0 +1,121 @@
/*
* Copyright 2022 The Android Open Source Project
* Copyright (c) 2022 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
*
* https://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.x.tests.uitests
import android.content.res.Configuration
import android.os.LocaleList
import androidx.activity.OnBackPressedDispatcher
import androidx.activity.OnBackPressedDispatcherOwner
import androidx.activity.compose.LocalOnBackPressedDispatcherOwner
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.unit.Density
import app.cash.paparazzi.Paparazzi
import com.airbnb.android.showkase.models.Showkase
import com.google.testing.junit.testparameterinjector.TestParameter
import com.google.testing.junit.testparameterinjector.TestParameterInjector
import io.element.android.x.designsystem.ElementXTheme
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
import java.util.Locale
/**
* BMA: Inspired from https://github.com/airbnb/Showkase/blob/master/showkase-screenshot-testing-paparazzi-sample/src/test/java/com/airbnb/android/showkase/screenshot/testing/paparazzi/sample/PaparazziSampleScreenshotTest.kt
*/
/*
* Credit to Alex Vanyo for creating this sample in the Now In Android app by Google.
* PR here - https://github.com/android/nowinandroid/pull/101. Modified the test from that PR to
* my own needs for this sample.
*/
@RunWith(TestParameterInjector::class)
class ScreenshotTest {
object PreviewProvider : TestParameter.TestParameterValuesProvider {
override fun provideValues(): List<TestPreview> {
val metadata = Showkase.getMetadata()
val components = metadata.componentList.map(::ComponentTestPreview)
val colors = metadata.colorList.map(::ColorTestPreview)
val typography = metadata.typographyList.map(::TypographyTestPreview)
return components + colors + typography
}
}
@get:Rule
val paparazzi = Paparazzi(
maxPercentDifference = 0.0,
)
@Test
fun preview_tests(
@TestParameter(valuesProvider = PreviewProvider::class) componentTestPreview: TestPreview,
@TestParameter baseDeviceConfig: BaseDeviceConfig,
@TestParameter(value = ["1.0"/*, "1.5"*/]) fontScale: Float,
@TestParameter(value = ["light", "dark"]) theme: String,
@TestParameter(value = ["en" /*"fr", "de", "ru"*/]) localeStr: String,
) {
paparazzi.unsafeUpdateConfig(
deviceConfig = baseDeviceConfig.deviceConfig.copy(
softButtons = false,
)
)
paparazzi.snapshot {
val lifecycleOwner = LocalLifecycleOwner.current
CompositionLocalProvider(
LocalInspectionMode provides true,
LocalDensity provides Density(
density = LocalDensity.current.density,
fontScale = fontScale
),
LocalConfiguration provides Configuration().apply {
setLocales(LocaleList(localeStr.toLocale()))
},
// Needed so that UI that uses it don't crash during screenshot tests
LocalOnBackPressedDispatcherOwner provides object : OnBackPressedDispatcherOwner {
override fun getLifecycle() = lifecycleOwner.lifecycle
override fun getOnBackPressedDispatcher() = OnBackPressedDispatcher()
}
) {
ElementXTheme(darkTheme = (theme == "dark")) {
Box(modifier = Modifier.background(MaterialTheme.colorScheme.background)) {
componentTestPreview.Content()
}
}
}
}
}
}
private fun String.toLocale(): Locale {
return when (this) {
"en" -> Locale.ENGLISH
"fr" -> Locale.FRANCE
"de" -> Locale.GERMAN
else -> Locale.Builder().setLanguage(this).build()
}
}

24
tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/TestPreview.kt

@ -0,0 +1,24 @@ @@ -0,0 +1,24 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import androidx.compose.runtime.Composable
interface TestPreview {
@Composable
fun Content()
}

48
tests/uitests/src/test/kotlin/io/element/android/x/tests/uitests/TypographyTestPreview.kt

@ -0,0 +1,48 @@ @@ -0,0 +1,48 @@
/*
* Copyright (c) 2022 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.x.tests.uitests
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.BasicText
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import com.airbnb.android.showkase.models.ShowkaseBrowserTypography
import com.airbnb.android.showkase.ui.padding4x
import java.util.Locale
class TypographyTestPreview(
private val showkaseBrowserTypography: ShowkaseBrowserTypography
) : TestPreview {
@Composable
override fun Content() {
BasicText(
text = showkaseBrowserTypography.typographyName.replaceFirstChar {
it.titlecase(Locale.getDefault())
},
modifier = Modifier
.fillMaxWidth()
.padding(padding4x),
style = showkaseBrowserTypography.textStyle.copy(
color = MaterialTheme.colorScheme.onBackground
)
)
}
override fun toString(): String = "Typo_${showkaseBrowserTypography.typographyGroup}_${showkaseBrowserTypography.typographyName}"
}

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_DarkGrey,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_DarkGrey,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_LightGrey,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Color_Material Design_LightGrey,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Body Large,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Body Large,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Headline Small,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[Typo_Element_Headline Small,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.avatar_null_DefaultGroup_InitialsAvatarPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.avatar_null_DefaultGroup_InitialsAvatarPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ConfirmationDialogPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ConfirmationDialogPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ErrorDialogPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.dialogs_null_DefaultGroup_ErrorDialogPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceCategoryPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceCategoryPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceScreenPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceScreenPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSlidePreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSlidePreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSwitchPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceSwitchPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceTextPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components.preferences_null_DefaultGroup_PreferenceTextPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_LabelledCheckboxPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_LabelledCheckboxPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_ProgressDialogPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.designsystem.components_null_DefaultGroup_ProgressDialogPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.changeserver_null_DefaultGroup_ChangeServerContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.changeserver_null_DefaultGroup_ChangeServerContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.root_null_DefaultGroup_LoginContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.login.root_null_DefaultGroup_LoginContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.logout_null_DefaultGroup_LogoutContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.logout_null_DefaultGroup_LogoutContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__0,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__0,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__1,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__1,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__2,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__2,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__3,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__3,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__4,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__4,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__5,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.messages.timeline_null_DefaultGroup_TimelineItemsPreview__5,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.preferences.root_null_DefaultGroup_PreferencesContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.preferences.root_null_DefaultGroup_PreferencesContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.bugreport_null_DefaultGroup_BugReportContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.bugreport_null_DefaultGroup_BugReportContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.crash.ui_null_DefaultGroup_CrashDetectionContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.crash.ui_null_DefaultGroup_CrashDetectionContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.detection_null_DefaultGroup_RageshakeDialogContentPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.detection_null_DefaultGroup_RageshakeDialogContentPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.preferences_null_DefaultGroup_RageshakePreferenceNotSupportedPreview_,NEXUS_5,1,dark,en].png (Stored with Git LFS)

Binary file not shown.

BIN
tests/uitests/src/test/snapshots/images/io.element.android.x.tests.uitests_ScreenshotTest_preview_tests[io.element.android.x.features.rageshake.preferences_null_DefaultGroup_RageshakePreferenceNotSupportedPreview_,NEXUS_5,1,light,en].png (Stored with Git LFS)

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save