mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-24 19:35:28 -06:00
ed2284c31a
* fix(macos): keep Canvas hidden for agent content operations Agent canvas.evalJS, canvas.snapshot, and canvas.a2ui.* commands routed through CanvasManager.show, which re-presented the panel and called NSApp.activate(ignoringOtherApps:) on every content update. After a gateway restart the hosted A2UI page is dead, so the next agent push always re-opened a panel the user had closed and stole focus. Content operations now use a non-presenting ensureController/prepare path; only canvas.present, canvas.navigate, and user actions reveal the panel. Snapshot is read-only: it requires a visible matching panel and returns CANVAS_HIDDEN instead of mutating panel state (WebKit cannot render ordered-out windows). * chore(i18n): refresh native inventory line offsets
81 lines
2.9 KiB
Swift
81 lines
2.9 KiB
Swift
import Foundation
|
|
import Testing
|
|
@testable import OpenClaw
|
|
|
|
@Suite(.serialized)
|
|
@MainActor
|
|
struct CanvasManagerVisibilityTests {
|
|
@Test func `eval on fresh state creates a hidden surface`() async throws {
|
|
let manager = CanvasManager.shared
|
|
manager._testResetPanel()
|
|
defer { manager._testResetPanel() }
|
|
|
|
let result = try await manager.eval(sessionKey: "visibility-eval", javaScript: "1 + 1")
|
|
|
|
#expect(result == "2")
|
|
#expect(manager._testHasPanelController)
|
|
#expect(manager._testPanelWindowIsVisible == false)
|
|
}
|
|
|
|
@Test func `showDetailed presents the panel`() throws {
|
|
let manager = CanvasManager.shared
|
|
manager._testResetPanel()
|
|
defer { manager._testResetPanel() }
|
|
|
|
_ = try manager.showDetailed(sessionKey: "visibility-present")
|
|
|
|
#expect(manager._testPanelWindowIsVisible == true)
|
|
}
|
|
|
|
@Test func `content operations respect a user hide`() async throws {
|
|
let manager = CanvasManager.shared
|
|
manager._testResetPanel()
|
|
defer { manager._testResetPanel() }
|
|
|
|
_ = try manager.showDetailed(sessionKey: "visibility-hidden")
|
|
manager.hideAll()
|
|
try manager.prepare(sessionKey: "visibility-hidden", target: "/")
|
|
_ = try await manager.eval(sessionKey: "visibility-hidden", javaScript: "1 + 1")
|
|
|
|
#expect(manager._testPanelWindowIsVisible == false)
|
|
}
|
|
|
|
@Test func `snapshot while hidden throws without presenting`() async throws {
|
|
let manager = CanvasManager.shared
|
|
manager._testResetPanel()
|
|
defer { manager._testResetPanel() }
|
|
|
|
let output = FileManager.default.temporaryDirectory
|
|
.appendingPathComponent("openclaw-canvas-hidden-\(UUID().uuidString).png")
|
|
defer { try? FileManager.default.removeItem(at: output) }
|
|
|
|
try manager.prepare(sessionKey: "visibility-snapshot", target: "/")
|
|
do {
|
|
_ = try await manager.snapshot(sessionKey: "visibility-snapshot", outPath: output.path)
|
|
Issue.record("hidden snapshot should throw CANVAS_HIDDEN")
|
|
} catch {
|
|
#expect(error.localizedDescription.contains("CANVAS_HIDDEN"))
|
|
}
|
|
|
|
#expect(manager._testHasPanelController)
|
|
#expect(manager._testPanelWindowIsVisible == false)
|
|
#expect(FileManager.default.fileExists(atPath: output.path) == false)
|
|
}
|
|
|
|
@Test func `snapshot for another session leaves the visible panel alone`() async throws {
|
|
let manager = CanvasManager.shared
|
|
manager._testResetPanel()
|
|
defer { manager._testResetPanel() }
|
|
|
|
_ = try manager.showDetailed(sessionKey: "visibility-live")
|
|
#expect(manager._testPanelWindowIsVisible == true)
|
|
|
|
await #expect(throws: (any Error).self) {
|
|
try await manager.snapshot(sessionKey: "visibility-other", outPath: nil)
|
|
}
|
|
|
|
// Read-only snapshot must not close or switch the live panel.
|
|
#expect(manager._testPanelWindowIsVisible == true)
|
|
}
|
|
}
|