commit fe67f7effc659549501cecae3a6743dc448b6f26
parent b54b08da083d280b0c2797f1b72133719bb75714
Author: triesap <tyson@radroots.org>
Date: Fri, 14 Aug 2026 17:56:08 +0000
test: qualify macOS window chrome integration
- Exercise safe-area bounds through the production identity lifecycle
- Pin refreshed macOS golden digests in governed design evidence
- Preserve fail-fast host policy across bootstrap and dashboard states
- Verify governed checks, development preparation, and host packaging
Diffstat:
3 files changed, 48 insertions(+), 17 deletions(-)
diff --git a/app/desktop/src/hostUiTest/kotlin/org/harvestcircle/hostui/IdentityLifecycleHostUiTest.kt b/app/desktop/src/hostUiTest/kotlin/org/harvestcircle/hostui/IdentityLifecycleHostUiTest.kt
@@ -3,6 +3,7 @@ package org.harvestcircle.hostui
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.setValue
+import androidx.compose.ui.test.ComposeUiTest
import androidx.compose.ui.test.ExperimentalTestApi
import androidx.compose.ui.test.assertCountEquals
import androidx.compose.ui.test.assertIsDisplayed
@@ -26,6 +27,9 @@ import org.harvestcircle.application.SecretClipboardController
import org.harvestcircle.application.TextClipboard
import org.harvestcircle.application.UnixSeconds
import org.harvestcircle.application.desktopRuntimeOpenConfiguration
+import org.harvestcircle.designsystem.layout.HarvestCircleWindowChromeEnvironment
+import org.harvestcircle.designsystem.layout.HarvestCircleWindowChromeExclusion
+import org.harvestcircle.desktop.desktopWindowChromeExclusion
import java.nio.file.Files
import java.nio.file.Path
import kotlin.test.Test
@@ -51,27 +55,32 @@ class IdentityLifecycleHostUiTest {
lateinit var presenter: HarvestCirclePresenter
var closeRequested by mutableStateOf(false)
var approvedExits = 0
+ val windowChromeExclusion = desktopWindowChromeExclusion(hostIsMacOs())
try {
setContent {
- HarvestCircleApplicationWithDependencies(
- closeRequested = closeRequested,
- onExitApproved = { approvedExits += 1 },
- clipboardFactory = { scope ->
- SecretClipboardController(scope, EmptyClipboard(), clearDelayMillis = 60_000)
- },
- ) { scope ->
- HarvestCirclePresenter(
- runtime = runtime,
- scope = scope,
- clock = ApplicationClock { UnixSeconds(System.currentTimeMillis() / 1_000) },
- operationIds = operationIds,
- ).also { presenter = it }
+ HarvestCircleWindowChromeEnvironment(windowChromeExclusion) {
+ HarvestCircleApplicationWithDependencies(
+ closeRequested = closeRequested,
+ onExitApproved = { approvedExits += 1 },
+ clipboardFactory = { scope ->
+ SecretClipboardController(scope, EmptyClipboard(), clearDelayMillis = 60_000)
+ },
+ ) { scope ->
+ HarvestCirclePresenter(
+ runtime = runtime,
+ scope = scope,
+ clock = ApplicationClock { UnixSeconds(System.currentTimeMillis() / 1_000) },
+ operationIds = operationIds,
+ ).also { presenter = it }
+ }
}
}
waitForTag("bootstrap-welcome")
+ assertCanvasChromeClearance(windowChromeExclusion)
onNodeWithTag("bootstrap-read-only").performClick()
waitForTag("foundation-today")
+ assertDashboardChromeClearance(windowChromeExclusion)
onNodeWithTag("top-bar-signer").performClick()
waitForTag("signer-add-or-activate-identity")
onNodeWithTag("signer-add-or-activate-identity").performClick()
@@ -137,6 +146,23 @@ class IdentityLifecycleHostUiTest {
runCatching { onNodeWithTag(tag).assertIsEnabled() }.isSuccess
}
}
+
+ private fun ComposeUiTest.assertCanvasChromeClearance(exclusion: HarvestCircleWindowChromeExclusion) {
+ if (exclusion == HarvestCircleWindowChromeExclusion.None) return
+ val canvas = onNodeWithTag("canvas-scaffold").fetchSemanticsNode().boundsInRoot
+ val content = onNodeWithTag("harvestcircle-canvas-chrome-content").fetchSemanticsNode().boundsInRoot
+ val exclusionWidth = with(density) { exclusion.width.toPx() }
+ assertTrue(content.left >= canvas.left + exclusionWidth)
+ }
+
+ private fun ComposeUiTest.assertDashboardChromeClearance(exclusion: HarvestCircleWindowChromeExclusion) {
+ if (exclusion == HarvestCircleWindowChromeExclusion.None) return
+ val frame = onNodeWithTag("harvestcircle-frame").fetchSemanticsNode().boundsInRoot
+ val toggle = onNodeWithTag("workspace-sidebar-toggle").fetchSemanticsNode().boundsInRoot
+ val exclusionWidth = with(density) { exclusion.width.toPx() }
+ assertTrue(toggle.left >= frame.left + exclusionWidth)
+ onAllNodesWithTag("top-bar-sidebar-toggle").assertCountEquals(0)
+ }
}
private fun cleanupRuntime(
@@ -178,3 +204,8 @@ private fun deleteTree(root: Path) {
}
private const val UI_TIMEOUT_MILLIS = 15_000L
+
+private fun hostIsMacOs(): Boolean =
+ System
+ .getProperty("os.name", "")
+ .startsWith("Mac", ignoreCase = true)
diff --git a/config/design/source_baseline_v1.toml b/config/design/source_baseline_v1.toml
@@ -9,8 +9,8 @@ source_license = "GPL-3.0-only"
golden_host = "macos-aarch64"
golden_status = "verified"
golden_source_snapshot_sha256 = "c2fe49f3c3ea43105cb2fff4a67c7cd9c21561c71825440a91654a0c1b12e3b8"
-golden_light_sha256 = "01fab45de6622497568b7655aac59d4e65a64e7c41a314bb2453fae56893f515"
-golden_dark_sha256 = "187ba53d1c71ebe2bb7c072a68697c0217d537e58c4f72a6115df4120972913c"
+golden_light_sha256 = "96e1ef5dd8b5cb14e47471a737a1e57ab0543b7f3aa79b865051e4740a2ee57a"
+golden_dark_sha256 = "6a85cd890109b11de6f647dca91cb616651e362aa0802c40aa6aee7f678451c9"
[[mapping]]
source = "core/designsystem/src/commonMain"
diff --git a/tools/xtask/src/lib.rs b/tools/xtask/src/lib.rs
@@ -942,12 +942,12 @@ fn design_source_audit(root: &Path, inventory: &Inventory, findings: &mut Vec<St
(
"app/shared/src/desktopTest/resources/goldens/macos-aarch64/design-surface-light.png",
"golden_light_sha256",
- "01fab45de6622497568b7655aac59d4e65a64e7c41a314bb2453fae56893f515",
+ "96e1ef5dd8b5cb14e47471a737a1e57ab0543b7f3aa79b865051e4740a2ee57a",
),
(
"app/shared/src/desktopTest/resources/goldens/macos-aarch64/design-surface-dark.png",
"golden_dark_sha256",
- "187ba53d1c71ebe2bb7c072a68697c0217d537e58c4f72a6115df4120972913c",
+ "6a85cd890109b11de6f647dca91cb616651e362aa0802c40aa6aee7f678451c9",
),
] {
let authority = format!("{key} = \"{sha256}\"");