Merge pull request #7831 from element-hq/feature/bma/fixScreenshotFlakiness

Stop rewriting screenshots that did not meaningfully change
This commit is contained in:
Benoit Marty
2026-10-01 17:43:25 +02:00
committed by GitHub
9 changed files with 94 additions and 68 deletions
@@ -1,40 +0,0 @@
/*
* Copyright (c) 2026 Element Creations Ltd.
*
* SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial.
* Please see LICENSE files in the repository root for full details.
*/
package ui
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
/**
* Workaround for Paparazzi 2.0.0-alpha05 / LayoutLib 16.2.1 bug where
* HandlerThread_Delegate calls Thread.setPosixNicenessInternal which doesn't exist on JVM.
* Tracked in https://github.com/cashapp/paparazzi/issues/2342 — fixed in layoutlib 16.2.3.
* Remove this workaround once Paparazzi ships with layoutlib >= 16.2.3.
*
* Paparazzi's PaparazziLogger collects background thread errors and re-throws them via
* assertNoErrors(). This Statement wrapper catches the known NoSuchMethodError so the test
* can pass despite the LayoutLib bug.
*/
class LayoutLibErrorFilterStatement : TestRule {
override fun apply(base: Statement, description: Description): Statement {
return object : Statement() {
@Throws(Throwable::class)
override fun evaluate() {
try {
base.evaluate()
} catch (e: NoSuchMethodError) {
if (e.message?.contains("setPosixNicenessInternal") != true) throw e
} catch (npe: NullPointerException) {
// Also catch this error on `HorizontalFloatingToolbarPreview` and `HorizontalFloatingToolbarNoFabPreview`
if (npe.message?.contains("""Cannot invoke "java.util.ArrayList.size()" because "childrenList" is null""") != true) throw npe
}
}
}
}
}
@@ -29,10 +29,7 @@ class PreviewA11yTest(
@TestParameter(valuesProvider = ComposableA11yPreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
@get:Rule
val paparazziRule = PaparazziPreviewRule.createFor(
preview = preview,
locale = "en",
@@ -28,10 +28,7 @@ class PreviewShard1Test(
@TestParameter(valuesProvider = Shard1ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
@get:Rule
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test
@@ -28,10 +28,7 @@ class PreviewShard2Test(
@TestParameter(valuesProvider = Shard2ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
@get:Rule
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test
@@ -28,10 +28,7 @@ class PreviewShard3Test(
@TestParameter(valuesProvider = Shard3ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
@get:Rule
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test
@@ -28,10 +28,7 @@ class PreviewShard4Test(
@TestParameter(valuesProvider = Shard4ComposablePreviewProvider::class)
val preview: ComposablePreview<AndroidPreviewInfo>,
) {
@get:Rule(order = 0)
val layoutLibErrorFilterStatement = LayoutLibErrorFilterStatement()
@get:Rule(order = 1)
@get:Rule
val paparazziRule = PaparazziPreviewRule.createFor(preview, locale = "en")
@Test