Unify screenshot references path overriding

commit_hash:14ece8061daff3f6c9471a7e1b91d4ff4de6970e
This commit is contained in:
grechka62
2026-03-27 09:04:31 +03:00
parent c274535498
commit 54d8df3855
5 changed files with 37 additions and 56 deletions
@@ -4,8 +4,6 @@ import android.app.Activity
import android.content.Context
import android.content.Intent
import androidx.test.core.app.ApplicationProvider
import com.yandex.div.Div2ScreenshotTest.Companion.PRODUCTION_CASES_PATH
import com.yandex.div.Div2ScreenshotTest.Companion.TEST_CASES_PATH
import com.yandex.div.Div2ScreenshotTest.Companion.relativePath
import com.yandex.div.rule.screenshotRule
import com.yandex.divkit.demo.R
@@ -13,11 +11,7 @@ import com.yandex.divkit.demo.screenshot.DivScreenshotActivity
import com.yandex.test.idling.ActivityIdlingResource
import com.yandex.test.idling.waitForIdlingResource
import com.yandex.test.rules.ActivityParamsTestRule
import com.yandex.test.screenshot.DIV_SCREENSHOT_CASE_EXTENSION
import com.yandex.test.screenshot.ReferenceFileWriter
import com.yandex.test.screenshot.Screenshot
import com.yandex.test.screenshot.ScreenshotType
import com.yandex.test.screenshot.caseName
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -34,43 +28,22 @@ class Div2RebindScreenshotTest(private val case: String, escapedCase: String) {
@Rule
@JvmField
val rule = screenshotRule(case, activityRule, case.relativePath)
val rule = screenshotRule(case, activityRule, case.relativePath, expectedSuite)
@Screenshot(viewId = R.id.screenshot_view)
@Test
fun divScreenshot() {
context.sendBroadcastAndWait<DivScreenshotActivity>(DivScreenshotActivity.REBIND_DIV_WITH_SAME_DATA_ACTION)
createReferenceOverride()
}
private fun createReferenceOverride() {
val caseRelativePath = case.relativePath
val caseName = case.caseName
ScreenshotType.values().forEach {
val targetSuiteName = "${Div2RebindScreenshotTest::class.qualifiedName}/$caseRelativePath"
val actualSuiteName = "${Div2ScreenshotTest::class.qualifiedName}/$caseRelativePath"
ReferenceFileWriter.append(
it.relativeScreenshotPath(targetSuiteName, caseName),
it.relativeScreenshotPath(actualSuiteName, caseName)
)
}
}
companion object {
private val context: Context = ApplicationProvider.getApplicationContext()
private val expectedSuite = Div2ScreenshotTest::class.qualifiedName ?: ""
@JvmStatic
@Parameters(name = "{1}")
fun cases(): List<Array<String>> {
val filter = { filename: String ->
filename.endsWith(DIV_SCREENSHOT_CASE_EXTENSION) && !filename.contains("templates")
}
val testCases = AssetEnumerator(context).enumerate(TEST_CASES_PATH, filter)
val productionCases = AssetEnumerator(context).enumerate(PRODUCTION_CASES_PATH, filter)
return (testCases + productionCases).withEscapedParameter()
}
fun cases() = Div2ScreenshotTest.cases()
}
}
@@ -34,22 +34,19 @@ class Div2ScreenshotTest(case: String, escapedCase: String) {
companion object {
const val TEST_CASES_PATH = "snapshot_test_data"
const val PRODUCTION_CASES_PATH = "production_data"
private val context: Context = ApplicationProvider.getApplicationContext()
private val context: Context get() = ApplicationProvider.getApplicationContext()
@JvmStatic
@Parameters(name = "{1}")
fun cases(): List<Array<String>> {
val filter = { filename: String -> filename.endsWith(DIV_SCREENSHOT_CASE_EXTENSION) }
val testCases = AssetEnumerator(context).enumerate(TEST_CASES_PATH, filter)
val productionCases = AssetEnumerator(context).enumerate(PRODUCTION_CASES_PATH, filter)
return (testCases + productionCases).withEscapedParameter()
return testCases.withEscapedParameter()
}
val String.relativePath: String get() {
return substringAfter("$TEST_CASES_PATH${File.separator}")
.substringAfter("$PRODUCTION_CASES_PATH${File.separator}")
.substringBeforeLast(File.separator)
}
}
@@ -25,13 +25,11 @@ fun screenshotRule(
casePath: String,
activityRule: ActivityParamsTestRule<out Activity>,
relativePath: String = "",
expectedSuite: String = "",
): TestRule {
val screenshotRule = ScreenshotRule(relativePath, casePath)
screenshotRule.beforeScreenshotTaken {
return screenshotRule(casePath, activityRule, relativePath, expectedSuite) {
waitForImages { activityRule.activity as? DivScreenshotActivity }
}
return baseRule(casePath, activityRule)
.chain(screenshotRule)
}
fun composeScreenshotRule(
@@ -39,10 +37,20 @@ fun composeScreenshotRule(
activityRule: ActivityParamsTestRule<DivComposeScreenshotActivity>,
relativePath: String = "",
): TestRule {
val screenshotRule = ScreenshotRule(relativePath, casePath)
screenshotRule.beforeScreenshotTaken {
return screenshotRule(casePath, activityRule, relativePath, "") {
waitForIdlingResource(activityRule.activity.imageLoadingTracker)
}
}
private fun screenshotRule(
casePath: String,
activityRule: ActivityParamsTestRule<out Activity>,
relativePath: String,
expectedSuite: String,
waitForImages: () -> Unit
): TestRule {
val screenshotRule = ScreenshotRule(casePath, relativePath, expectedSuite)
screenshotRule.beforeScreenshotTaken(waitForImages)
return baseRule(casePath, activityRule)
.chain(screenshotRule)
}
@@ -6,8 +6,9 @@ import org.junit.runner.Description
import org.junit.runners.model.Statement
class ScreenshotRule(
private val casePath: String,
private val relativePath: String,
private val casePath: String
private val expectedSuite: String,
) : TestRule {
private var beforeScreenshotTakenAction: (() -> Unit)? = null
@@ -20,6 +21,7 @@ class ScreenshotRule(
val screenshot = description.getAnnotation(Screenshot::class.java) ?: return base
val screenshotPath = screenshot.relativePath.ifEmpty { relativePath }
val suiteName = description.className + "/" + screenshotPath
val expectedSuite = if (expectedSuite.isNotEmpty()) "$expectedSuite/$screenshotPath" else ""
return object : Statement() {
override fun evaluate() {
base.evaluate()
@@ -27,7 +29,7 @@ class ScreenshotRule(
val view = waitForView(screenshot.viewId)
beforeScreenshotTakenAction?.invoke()
captureScreenshots(view, suiteName, casePath, screenshot.name)
captureScreenshots(view, suiteName, casePath, screenshot.name, expectedSuite = expectedSuite)
}
}
}
@@ -17,7 +17,8 @@ fun captureScreenshots(
casePath: String,
screenshotName: String = "",
stepId: Int? = null,
expectedScreenshot: String = ""
expectedScreenshot: String = "",
expectedSuite: String = "",
) {
val (suiteName, caseName) = when {
screenshotName.isNotEmpty() -> artifactsRelativePath to screenshotName
@@ -29,19 +30,19 @@ fun captureScreenshots(
val screenshots = ScreenshotCaptor.takeScreenshots(view, suiteName, caseName)
TestCaseReferencesFileWriter.append(casePath, screenshots)
if (expectedScreenshot.isEmpty()) return@runOnMainSync
if (expectedScreenshot.isEmpty() && expectedSuite.isEmpty()) return@runOnMainSync
val expected = expectedScreenshot.substringBefore(ScreenshotType.SCREENSHOT_EXTENSION)
if (expected == caseName) return@runOnMainSync
val expected = expectedScreenshot.takeIf { it.isNotEmpty() }
?.substringBefore(ScreenshotType.SCREENSHOT_EXTENSION)
?: caseName
if (expected == caseName && expectedSuite.isEmpty()) return@runOnMainSync
appendReference(ScreenshotType.ViewRender, suiteName, caseName, expected)
appendReference(ScreenshotType.ViewPixelCopy, suiteName, caseName, expected)
val expectedSuite = expectedSuite.takeIf { it.isNotEmpty() } ?: suiteName
ScreenshotType.values().forEach {
ReferenceFileWriter.append(
targetFile = it.relativeScreenshotPath(suiteName, caseName),
compareWith = it.relativeScreenshotPath(expectedSuite, expected)
)
}
}
}
private fun appendReference(type: ScreenshotType, suiteName: String, actual: String, expected: String) {
ReferenceFileWriter.append(
targetFile = type.relativeScreenshotPath(suiteName, actual),
compareWith = type.relativeScreenshotPath(suiteName, expected)
)
}