diff --git a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt
index bb625370cf..02e53fbb1c 100644
--- a/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt
+++ b/features/rageshake/api/src/main/kotlin/io/element/android/features/rageshake/api/reporter/BugReporter.kt
@@ -18,6 +18,7 @@ interface BugReporter {
* @param withScreenshot true to include the screenshot
* @param problemDescription the bug description
* @param canContact true if the user opt in to be contacted directly
+ * @param sendPushRules true to include the push rules
* @param listener the listener
*/
suspend fun sendBugReport(
@@ -26,6 +27,7 @@ interface BugReporter {
withScreenshot: Boolean,
problemDescription: String,
canContact: Boolean = false,
+ sendPushRules: Boolean = false,
listener: BugReporterListener
)
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportEvents.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportEvents.kt
index fbf2906623..1b0a61e1d5 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportEvents.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportEvents.kt
@@ -16,4 +16,5 @@ sealed interface BugReportEvents {
data class SetSendLog(val sendLog: Boolean) : BugReportEvents
data class SetCanContact(val canContact: Boolean) : BugReportEvents
data class SetSendScreenshot(val sendScreenshot: Boolean) : BugReportEvents
+ data class SetSendPushRules(val sendPushRules: Boolean) : BugReportEvents
}
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt
index 4faef73589..bfcfcf424e 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenter.kt
@@ -105,6 +105,9 @@ class BugReportPresenter(
is BugReportEvents.SetSendScreenshot -> updateFormState(formState) {
copy(sendScreenshot = event.sendScreenshot)
}
+ is BugReportEvents.SetSendPushRules -> updateFormState(formState) {
+ copy(sendPushRules = event.sendPushRules)
+ }
BugReportEvents.ClearError -> {
sendingProgress.floatValue = 0f
sendingAction.value = AsyncAction.Uninitialized
@@ -137,6 +140,7 @@ class BugReportPresenter(
withScreenshot = formState.sendScreenshot,
problemDescription = formState.description,
canContact = formState.canContact,
+ sendPushRules = formState.sendPushRules,
listener = listener
)
}
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt
index 8922446329..54b8608add 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportState.kt
@@ -29,14 +29,16 @@ data class BugReportFormState(
val description: String,
val sendLogs: Boolean,
val canContact: Boolean,
- val sendScreenshot: Boolean
+ val sendScreenshot: Boolean,
+ val sendPushRules: Boolean,
) : Parcelable {
companion object {
val Default = BugReportFormState(
description = "",
sendLogs = true,
canContact = false,
- sendScreenshot = false
+ sendScreenshot = false,
+ sendPushRules = false,
)
}
}
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt
index 760106b0fb..95dff10804 100644
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportView.kt
@@ -7,6 +7,7 @@
package io.element.android.features.rageshake.impl.bugreport
+import android.content.res.Configuration
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
@@ -26,6 +27,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardCapitalization
import androidx.compose.ui.text.input.KeyboardType
+import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
@@ -40,7 +42,6 @@ import io.element.android.libraries.designsystem.components.preferences.Preferen
import io.element.android.libraries.designsystem.components.preferences.PreferenceSwitch
import io.element.android.libraries.designsystem.modifiers.onTabOrEnterKeyFocusNext
import io.element.android.libraries.designsystem.preview.ElementPreview
-import io.element.android.libraries.designsystem.preview.PreviewsDayNight
import io.element.android.libraries.designsystem.theme.components.Button
import io.element.android.libraries.designsystem.theme.components.ListItem
import io.element.android.libraries.designsystem.theme.components.Text
@@ -142,6 +143,13 @@ fun BugReportView(
}
}
}
+ PreferenceSwitch(
+ isChecked = state.formState.sendPushRules,
+ onCheckedChange = { eventSink(BugReportEvents.SetSendPushRules(it)) },
+ enabled = isFormEnabled,
+ title = stringResource(R.string.screen_bug_report_send_notification_settings_title),
+ subtitle = stringResource(R.string.screen_bug_report_send_notification_settings_description),
+ )
// Submit
PreferenceRow {
Button(
@@ -174,9 +182,20 @@ fun BugReportView(
}
}
-@PreviewsDayNight
+@Preview(heightDp = 1000)
@Composable
-internal fun BugReportViewPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreview {
+internal fun BugReportViewDayPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreview {
+ BugReportView(
+ state = state,
+ onSuccess = {},
+ onBackClick = {},
+ onViewLogs = {},
+ )
+}
+
+@Preview(heightDp = 1000, uiMode = Configuration.UI_MODE_NIGHT_YES)
+@Composable
+internal fun BugReportViewNightPreview(@PreviewParameter(BugReportStateProvider::class) state: BugReportState) = ElementPreview {
BugReportView(
state = state,
onSuccess = {},
diff --git a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt
index 5787939688..a4651cc433 100755
--- a/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt
+++ b/features/rageshake/impl/src/main/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporter.kt
@@ -44,6 +44,7 @@ import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.asRequestBody
+import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import org.json.JSONException
import org.json.JSONObject
@@ -113,6 +114,7 @@ class DefaultBugReporter(
withScreenshot: Boolean,
problemDescription: String,
canContact: Boolean,
+ sendPushRules: Boolean,
listener: BugReporterListener,
) {
val url = bugReporterUrlProvider.provide().first()
@@ -181,6 +183,16 @@ class DefaultBugReporter(
if (curveKey != null && edKey != null) {
builder.addFormDataPart("device_keys", "curve25519:$curveKey, ed25519:$edKey")
}
+
+ if (sendPushRules) {
+ client.notificationSettingsService.getRawPushRules().getOrNull()?.let { pushRules ->
+ builder.addFormDataPart(
+ name = "file",
+ filename = "push_rules.json",
+ body = pushRules.toByteArray().toRequestBody(MimeTypes.Json.toMediaTypeOrNull())
+ )
+ }
+ }
}
}
if (crashCallStack.isNotEmpty() && withCrashLogs) {
diff --git a/features/rageshake/impl/src/main/res/values/localazy.xml b/features/rageshake/impl/src/main/res/values/localazy.xml
index f6d93c4114..85af2af4a7 100644
--- a/features/rageshake/impl/src/main/res/values/localazy.xml
+++ b/features/rageshake/impl/src/main/res/values/localazy.xml
@@ -14,7 +14,7 @@
"Send screenshot"
"Logs will be included with your message to make sure that everything is working properly. To send your message without logs, turn off this setting."
"%1$s crashed the last time it was used. Would you like to share a crash report with us?"
- "If you are having issues with notifications, uploading the notification settings can help us pinpoint the root cause."
+ "If you are having issues with notifications, uploading the notification push rules can help us pinpoint the root cause. Note these rules can contain private information, such as your display name or keywords to be notified for."
"Send notification settings"
"View logs"
diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt
index 362b3798d6..780377025e 100644
--- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt
+++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/BugReportPresenterTest.kt
@@ -106,6 +106,20 @@ class BugReportPresenterTest {
}
}
+ @Test
+ fun `present - send notification settings`() = runTest {
+ val presenter = createPresenter()
+ moleculeFlow(RecompositionMode.Immediate) {
+ presenter.present()
+ }.test {
+ val initialState = awaitItem()
+ initialState.eventSink.invoke(BugReportEvents.SetSendPushRules(true))
+ assertThat(awaitItem().formState).isEqualTo(BugReportFormState.Default.copy(sendPushRules = true))
+ initialState.eventSink.invoke(BugReportEvents.SetSendPushRules(false))
+ assertThat(awaitItem().formState).isEqualTo(BugReportFormState.Default.copy(sendPushRules = false))
+ }
+ }
+
@Test
fun `present - reset all`() = runTest {
val presenter = createPresenter(
diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt
index ebaa524bd5..bd9c538c0d 100644
--- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt
+++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/bugreport/FakeBugReporter.kt
@@ -26,6 +26,7 @@ class FakeBugReporter(val mode: Mode = Mode.Success) : BugReporter {
withScreenshot: Boolean,
problemDescription: String,
canContact: Boolean,
+ sendPushRules: Boolean,
listener: BugReporterListener,
) {
delay(100)
diff --git a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt
index ecb8d13b12..360b0fbbcb 100755
--- a/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt
+++ b/features/rageshake/impl/src/test/kotlin/io/element/android/features/rageshake/impl/reporter/DefaultBugReporterTest.kt
@@ -24,6 +24,7 @@ import io.element.android.libraries.matrix.test.FakeSdkMetadata
import io.element.android.libraries.matrix.test.auth.FakeMatrixAuthenticationService
import io.element.android.libraries.matrix.test.core.aBuildMeta
import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService
+import io.element.android.libraries.matrix.test.notificationsettings.FakeNotificationSettingsService
import io.element.android.libraries.matrix.test.tracing.FakeTracingService
import io.element.android.libraries.network.useragent.DefaultUserAgentProvider
import io.element.android.libraries.sessionstorage.api.SessionStore
@@ -65,6 +66,7 @@ class DefaultBugReporterTest {
withDevicesLogs = true,
withCrashLogs = true,
withScreenshot = true,
+ sendPushRules = true,
problemDescription = "a bug occurred",
canContact = true,
listener = object : BugReporterListener {
@@ -109,7 +111,12 @@ class DefaultBugReporterTest {
)
val fakeEncryptionService = FakeEncryptionService()
- val matrixClient = FakeMatrixClient(encryptionService = fakeEncryptionService)
+
+ val fakePushRules = "{ content: ... }"
+ val fakeNotificationSettingsService = FakeNotificationSettingsService(
+ getRawPushRulesResult = { Result.success(fakePushRules) }
+ )
+ val matrixClient = FakeMatrixClient(encryptionService = fakeEncryptionService, notificationSettingsService = fakeNotificationSettingsService)
fakeEncryptionService.givenDeviceKeys("CURVECURVECURVE", "EDKEYEDKEYEDKY")
val sut = createDefaultBugReporter(
@@ -124,6 +131,7 @@ class DefaultBugReporterTest {
withDevicesLogs = true,
withCrashLogs = true,
withScreenshot = true,
+ sendPushRules = true,
problemDescription = "a bug occurred",
canContact = true,
listener = object : BugReporterListener {
@@ -149,9 +157,11 @@ class DefaultBugReporterTest {
assertThat(foundValues["user_id"]).isEqualTo("@foo:example.com")
assertThat(foundValues["text"]).isEqualTo("a bug occurred")
assertThat(foundValues["device_keys"]).isEqualTo("curve25519:CURVECURVECURVE, ed25519:EDKEYEDKEYEDKY")
+ assertThat(foundValues["file"]).contains(fakePushRules)
// device_key now added given they are not null
- assertThat(progressValues.size).isEqualTo(EXPECTED_NUMBER_OF_PROGRESS_VALUE + 1)
+ // so is the push_rules value
+ assertThat(progressValues.size).isEqualTo(EXPECTED_NUMBER_OF_PROGRESS_VALUE + 2)
server.shutdown()
}
@@ -272,6 +282,7 @@ class DefaultBugReporterTest {
withDevicesLogs = true,
withCrashLogs = true,
withScreenshot = true,
+ sendPushRules = true,
problemDescription = "a bug occurred",
canContact = true,
listener = object : BugReporterListener {
diff --git a/libraries/core/src/main/kotlin/io/element/android/libraries/core/mimetype/MimeTypes.kt b/libraries/core/src/main/kotlin/io/element/android/libraries/core/mimetype/MimeTypes.kt
index 357fce2feb..f18702639f 100644
--- a/libraries/core/src/main/kotlin/io/element/android/libraries/core/mimetype/MimeTypes.kt
+++ b/libraries/core/src/main/kotlin/io/element/android/libraries/core/mimetype/MimeTypes.kt
@@ -13,6 +13,7 @@ import io.element.android.libraries.core.bool.orFalse
@Suppress("ktlint:standard:property-naming")
object MimeTypes {
const val Any: String = "*/*"
+ const val Json = "application/json"
const val OctetStream = "application/octet-stream"
const val Apk = "application/vnd.android.package-archive"
const val Pdf = "application/pdf"
diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt
index 703ec1205e..7f8b2e1c1f 100644
--- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt
+++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/notificationsettings/NotificationSettingsService.kt
@@ -33,4 +33,5 @@ interface NotificationSettingsService {
suspend fun setInviteForMeEnabled(enabled: Boolean): Result
suspend fun getRoomsWithUserDefinedRules(): Result>
suspend fun canHomeServerPushEncryptedEventsToDevice(): Result
+ suspend fun getRawPushRules(): Result
}
diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt
index b4f3e70754..40be78cf31 100644
--- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt
+++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/notificationsettings/RustNotificationSettingsService.kt
@@ -139,4 +139,8 @@ class RustNotificationSettingsService(
runCatchingExceptions {
notificationSettings.await().canPushEncryptedEventToDevice()
}
+
+ override suspend fun getRawPushRules(): Result = runCatchingExceptions {
+ notificationSettings.await().getRawPushRules()
+ }
}
diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt
index c5c09981fc..e23ccb30cc 100644
--- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt
+++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/notificationsettings/FakeNotificationSettingsService.kt
@@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.api.room.RoomNotificationMode
import io.element.android.libraries.matrix.api.room.RoomNotificationSettings
import io.element.android.libraries.matrix.test.A_ROOM_ID
import io.element.android.libraries.matrix.test.A_ROOM_NOTIFICATION_MODE
+import io.element.android.tests.testutils.lambda.lambdaError
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharedFlow
@@ -23,6 +24,7 @@ class FakeNotificationSettingsService(
initialEncryptedGroupDefaultMode: RoomNotificationMode = RoomNotificationMode.MENTIONS_AND_KEYWORDS_ONLY,
initialOneToOneDefaultMode: RoomNotificationMode = RoomNotificationMode.ALL_MESSAGES,
initialEncryptedOneToOneDefaultMode: RoomNotificationMode = RoomNotificationMode.ALL_MESSAGES,
+ private val getRawPushRulesResult: () -> Result = { lambdaError() },
) : NotificationSettingsService {
private val notificationSettingsStateFlow = MutableStateFlow(Unit)
private var defaultGroupRoomNotificationMode: RoomNotificationMode = initialGroupDefaultMode
@@ -178,4 +180,8 @@ class FakeNotificationSettingsService(
fun givenCanHomeServerPushEncryptedEventsToDeviceResult(result: Result) {
canHomeServerPushEncryptedEventsToDeviceResult = result
}
+
+ override suspend fun getRawPushRules(): Result {
+ return getRawPushRulesResult()
+ }
}
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_0_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_0_en.png
new file mode 100644
index 0000000000..df6127b08e
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_0_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3c229f0f963e247de755f45e55432191f88a51ba79baf49f0002c2c12dbdc09e
+size 48613
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_1_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_1_en.png
new file mode 100644
index 0000000000..830b19be50
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_1_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:cbf1430985870c99c6e6a2b427257235219250e1c6805bde44de64d1382bd30a
+size 113544
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_2_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_2_en.png
new file mode 100644
index 0000000000..cb45797e1f
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_2_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:5bc84691892f956b6d282ae5aff0a7ef7900aad754bb7f04e25582c25a256342
+size 45892
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_3_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_3_en.png
new file mode 100644
index 0000000000..df6127b08e
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_3_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:3c229f0f963e247de755f45e55432191f88a51ba79baf49f0002c2c12dbdc09e
+size 48613
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_4_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_4_en.png
new file mode 100644
index 0000000000..625d293aab
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewDay_4_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:26a5a053b88110ed76a59a99a199ada720fd7a44ff3b95546c4993ae3d8edddf
+size 37496
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_0_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_0_en.png
new file mode 100644
index 0000000000..d1fe942dc1
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_0_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c1020f77055e3369f012f73159be9e8c7bf582d4211b3b22f5409ecba46b6898
+size 47180
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_1_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_1_en.png
new file mode 100644
index 0000000000..fbbcced394
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_1_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:47c2e74119bd6f2329f15ee3b7dbf0115c69293bd34ed5c2e67de77319b7f820
+size 111436
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_2_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_2_en.png
new file mode 100644
index 0000000000..b0496a7ccb
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_2_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:984d43efa545fb9f104ea6d4eba87e768ade025eee8d1f74260049a64c7e7a7c
+size 44401
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_3_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_3_en.png
new file mode 100644
index 0000000000..d1fe942dc1
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_3_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:c1020f77055e3369f012f73159be9e8c7bf582d4211b3b22f5409ecba46b6898
+size 47180
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_4_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_4_en.png
new file mode 100644
index 0000000000..c6fed6a85c
--- /dev/null
+++ b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportViewNight_4_en.png
@@ -0,0 +1,3 @@
+version https://git-lfs.github.com/spec/v1
+oid sha256:41c5eb671aaa7c8666942dbc808eb7b03f81cbde98906c5c17cdee61b1d9566b
+size 35446
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_0_en.png
deleted file mode 100644
index 98aeade96c..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_0_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:c56f65335dcc9cda18ed7f647bf1dc9428ee07762ea3d40e7d28731a81ca8f2e
-size 69552
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_1_en.png
deleted file mode 100644
index 954d1ed9f9..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_1_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:12d9e6e297bbb3429a4fe6dd3ac16847280e479fe89e96ec78f35159a51d01f0
-size 108813
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_2_en.png
deleted file mode 100644
index 8f24a727e6..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_2_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:9b9e42889c2b31dfee71a644b2da66c0b7cf4f4f475030d7aab3a7d500e7246a
-size 66366
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_3_en.png
deleted file mode 100644
index 98aeade96c..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_3_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:c56f65335dcc9cda18ed7f647bf1dc9428ee07762ea3d40e7d28731a81ca8f2e
-size 69552
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_4_en.png
deleted file mode 100644
index a477999b9e..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Day_4_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:57402ade9b70c2124b6764edbaac71d30b89c49eea8175c448cbe7520867a42f
-size 49569
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_0_en.png
deleted file mode 100644
index 12f80074b2..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_0_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:38b5fb1099f10dae154270b5df1f52f4018d355d04e0040ba9c06ebe57f259c6
-size 67628
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_1_en.png
deleted file mode 100644
index ff52e5e80b..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_1_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:1a5920a102082f35d0f0a7171687998f568da5e2d68a9f9d9b5884c55c832bd2
-size 106479
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_2_en.png
deleted file mode 100644
index cd533fbb73..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_2_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:5035c2ffa678e1c761030fbac56dfb3afd043c25a3df0cd6fb7c83b2b311c2ae
-size 63678
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_3_en.png
deleted file mode 100644
index 12f80074b2..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_3_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:38b5fb1099f10dae154270b5df1f52f4018d355d04e0040ba9c06ebe57f259c6
-size 67628
diff --git a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_4_en.png
deleted file mode 100644
index d7be6c5994..0000000000
--- a/tests/uitests/src/test/snapshots/images/features.rageshake.impl.bugreport_BugReportView_Night_4_en.png
+++ /dev/null
@@ -1,3 +0,0 @@
-version https://git-lfs.github.com/spec/v1
-oid sha256:946751ac246e3e833ec39da86b25d80766daed29449b1d0fcebe33c5079b724a
-size 46418