Disable window tests by default
This commit is contained in:
1 parent
c283201b33
commit
d757d4eb2b
20 files changed
+43
-23
No files matched your search
@@ -28,7 +28,7 @@ Treat `Memory/` as durable engineering context. Read `ARCHITECTURE.md` before ch
|
||||
- `xcodebuild -project Termind.xcodeproj -scheme TFM -destination 'platform=macOS' -onlyUsePackageVersionsFromResolvedFile build` builds the app, the MCP bridge, and AgentKit. Keep the flag: resolving without it silently bumps pinned dependencies.
|
||||
- `xcodebuild -project Termind.xcodeproj -scheme TFI -destination 'generic/platform=iOS Simulator' -onlyUsePackageVersionsFromResolvedFile build` builds the mobile app and shared frameworks. Run its tests with an available iPhone or iPad simulator destination.
|
||||
- `cd ../AgentKit && swift build && swift test` builds and tests the agent package on its own.
|
||||
- `xcodebuild -project Termind.xcodeproj -scheme TFM -destination 'platform=macOS' -onlyUsePackageVersionsFromResolvedFile test` runs all Swift tests.
|
||||
- `xcodebuild -project Termind.xcodeproj -scheme TFM -destination 'platform=macOS' -onlyUsePackageVersionsFromResolvedFile test` runs the default macOS and shared Swift tests. Tests that show windows or take focus are opt-in.
|
||||
- `xcrun swift-format lint --strict --recursive Frameworks TFM TFI FrameworkTests TFMTests TFITests TermindMCPBridge` checks Swift formatting. AgentKit passes the same command over `Sources Tests` and must keep passing it.
|
||||
- `cd LandingPage && npm ci && npm run dev` installs locked web dependencies and starts Astro locally.
|
||||
- `cd LandingPage && npm run build` type-checks and emits the production site to `LandingPage/dist/`.
|
||||
@@ -39,7 +39,9 @@ Follow `.swift-format`: four spaces and 120 columns. Use PascalCase types, camel
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
Use Swift Testing (`@Suite`, `@Test`, `#expect`) in the three test directories. Add regression coverage and run all tests before submission. Web changes must pass `npm run build`; verify English and `/zh/` routes visually.
|
||||
Use Swift Testing (`@Suite`, `@Test`, `#expect`) in the three test directories. Add regression coverage and run the default test suite before submission. Web changes must pass `npm run build`; verify English and `/zh/` routes visually.
|
||||
|
||||
macOS tests that present windows or activate the app must use `.requiresVisibleWindow` on their suite or individual test. They are skipped by default; keep this opt-in off for routine verification. To opt in from the command line, prefix the test command with `TEST_RUNNER_TERMIND_WINDOW_TESTS=1` (Xcode forwards it as `TERMIND_WINDOW_TESTS=1` to the test host), preferably with `-only-testing:TFMTests/<Suite>` to limit the run. In Xcode, set `TERMIND_WINDOW_TESTS=1` in the test action's environment. Screenshot tests with existing dedicated opt-in variables keep those gates. Offscreen layout and logic tests remain enabled by default.
|
||||
|
||||
## Localization Guidelines
|
||||
|
||||
|
||||
@@ -324,6 +324,7 @@ struct BroadcastInputTests {
|
||||
|
||||
#if canImport(AppKit)
|
||||
@Test(
|
||||
.requiresVisibleWindow,
|
||||
.disabled(
|
||||
if: !ghosttyHasActiveDisplay,
|
||||
"Ghostty's Metal surface requires an active display"
|
||||
@@ -485,6 +486,7 @@ struct BroadcastInputTests {
|
||||
}
|
||||
|
||||
@Test(
|
||||
.requiresVisibleWindow,
|
||||
.disabled(
|
||||
if: !ghosttyHasActiveDisplay,
|
||||
"Ghostty's Metal surface requires an active display"
|
||||
|
||||
@@ -9,7 +9,7 @@ import struct TermindDomain.Host
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct ChooserInteractionTests {
|
||||
@Test(arguments: ["toolbar", "ssh", "serial"])
|
||||
func quickOpenTakesFocusAndHandlesTypingNavigationAndReopening(_ source: String) async throws {
|
||||
@@ -230,12 +230,12 @@ private final class ChooserFixture {
|
||||
print(
|
||||
"CHOOSER VIEWS",
|
||||
views.map {
|
||||
"\(type(of: $0)): \(($0 as? NSButton)?.title ?? "") \($0.accessibilityIdentifier() ?? "")"
|
||||
"\(Swift.type(of: $0)): \(($0 as? NSButton)?.title ?? "") \($0.accessibilityIdentifier())"
|
||||
})
|
||||
print(
|
||||
"CHOOSER AX",
|
||||
elements.map {
|
||||
"\(type(of: $0)): \($0.accessibilityLabel?() ?? "") \($0.accessibilityIdentifier?() ?? "")"
|
||||
"\(Swift.type(of: $0)): \($0.accessibilityLabel?() ?? "") \($0.accessibilityIdentifier?() ?? "")"
|
||||
})
|
||||
}
|
||||
return try #require(elements.first { $0.accessibilityIdentifier?() == identifier }, "Missing \(identifier)")
|
||||
|
||||
@@ -6,7 +6,7 @@ import Testing
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct HostIntegrationRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"], [320.0, 360.0, 480.0])
|
||||
func hostEditorShowsIntegrationBelowGroupingAtNarrowWidth(language: String, width: CGFloat) async throws {
|
||||
|
||||
@@ -8,7 +8,7 @@ import Testing
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct MemorySettingsRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"], [false, true])
|
||||
func memorySettingsRenderWithCapacity(_ language: String, dark: Bool) async throws {
|
||||
|
||||
@@ -8,7 +8,7 @@ import Testing
|
||||
@testable import Termind
|
||||
|
||||
@MainActor
|
||||
@Suite(.serialized)
|
||||
@Suite(.requiresVisibleWindow, .serialized)
|
||||
struct MetricsDetailToolbarTests {
|
||||
@Test(arguments: [AppLanguage.english, .simplifiedChinese, .traditionalChinese])
|
||||
func compactToolbarSwitchesPagesAndSearchRevealsProcesses(language: AppLanguage) async throws {
|
||||
|
||||
@@ -8,7 +8,7 @@ import struct TermindDomain.Host
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct MetricsJourneyRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func metricsAuthenticateInsideTheirJourneyWithoutOpeningAnExternalWindow(_ language: String) async throws {
|
||||
|
||||
@@ -10,7 +10,7 @@ import Testing
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
struct ModelProviderRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
@Test(.requiresVisibleWindow, arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func blankNameFormsPreviewTheSavedDefaults(_ language: String) async throws {
|
||||
let host = TermindDomain.Host(name: "AWS", host: "example.invalid")
|
||||
let enclave = SSHKeyRef(label: "", algorithm: .ecdsa256, storage: .secureEnclave)
|
||||
@@ -32,7 +32,7 @@ struct ModelProviderRenderingTests {
|
||||
language: language, name: "enclave-name-hint")
|
||||
}
|
||||
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
@Test(.requiresVisibleWindow, arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func anonymousProviderSettingsAndModelsRender(_ language: String) async throws {
|
||||
let provider = ModelProvider(
|
||||
name: "Local Model", inferenceURL: "http://localhost:11434/v1/chat/completions",
|
||||
@@ -50,7 +50,7 @@ struct ModelProviderRenderingTests {
|
||||
language: language, name: "provider-list")
|
||||
}
|
||||
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
@Test(.requiresVisibleWindow, arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func newProviderHintsAndVertexFieldsRender(_ language: String) async throws {
|
||||
let ai = AIConfigurationModel(persistsSecrets: false)
|
||||
let provider = ModelProvider(name: "")
|
||||
|
||||
@@ -8,7 +8,7 @@ import struct TermindDomain.Host
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct PortForwardingRenderingTests {
|
||||
@Test(arguments: [false, true])
|
||||
func saveClosesTheEditorOnlyAfterPersistenceSucceeds(_ fails: Bool) async throws {
|
||||
|
||||
@@ -63,6 +63,7 @@ struct RemoteWindowTitleTests {
|
||||
}
|
||||
|
||||
@Test(
|
||||
.requiresVisibleWindow,
|
||||
.disabled(
|
||||
if: !ghosttyHasActiveDisplay,
|
||||
"Ghostty's Metal surface requires an active display"
|
||||
|
||||
@@ -9,7 +9,7 @@ import Testing
|
||||
@MainActor
|
||||
@Suite(.serialized)
|
||||
struct ResponsivePageLayoutTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
@Test(.requiresVisibleWindow, arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func vaultEditorsKeepFieldsInsideNarrowColumns(_ language: String) async throws {
|
||||
let host = TermindDomain.Host(name: "Production Database Gateway with a Long Name", host: "server.invalid")
|
||||
let app = AppModel(hosts: HostLibraryModel(hosts: [host]))
|
||||
|
||||
@@ -11,7 +11,7 @@ import Testing
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
struct SFTPEditRenderingTests {
|
||||
@Test func menuHoverInspection() async throws {
|
||||
@Test(.requiresVisibleWindow) func menuHoverInspection() async throws {
|
||||
let model = SFTPEditModel()
|
||||
let hostID = UUID()
|
||||
let file = RemoteFile(
|
||||
@@ -80,7 +80,7 @@ struct SFTPEditRenderingTests {
|
||||
})
|
||||
}
|
||||
|
||||
@Test func floatingChangesFitNarrowPanesAndRenderOverFileRows() throws {
|
||||
@Test(.requiresVisibleWindow) func floatingChangesFitNarrowPanesAndRenderOverFileRows() throws {
|
||||
let model = SFTPEditModel()
|
||||
let hostID = UUID()
|
||||
for index in 0..<5 {
|
||||
|
||||
@@ -23,7 +23,7 @@ struct SFTPSettingsIntegrationTests {
|
||||
#expect(app.sftpTransfers.perHostLimit == 2)
|
||||
}
|
||||
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
@Test(.requiresVisibleWindow, arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func sftpSettingsRenderTheDefaultsAndMaximumLimits(language: String) async throws {
|
||||
let app = AppModel(hosts: HostLibraryModel())
|
||||
let model = WindowModel(workspaces: [])
|
||||
|
||||
@@ -4,7 +4,7 @@ import TermindApplication
|
||||
import TermindPresentation
|
||||
import Testing
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct SSHKeyboardInteractiveRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func rendersEchoAndSecretPrompts(_ language: String) async throws {
|
||||
|
||||
@@ -5,7 +5,7 @@ import Testing
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor struct SkillSettingsRenderingTests {
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor struct SkillSettingsRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans"])
|
||||
func aiSettingsShowUserSkillsAndMemoryAfterMCP(_ language: String) async throws {
|
||||
let app = AppModel(hosts: HostLibraryModel(), skills: SkillLibraryModel())
|
||||
|
||||
@@ -12,7 +12,8 @@ private nonisolated let terminalMouseHasDisplay: Bool = {
|
||||
return CGGetActiveDisplayList(0, nil, &count) == .success && count > 0
|
||||
}()
|
||||
|
||||
@Suite(.serialized, .disabled(if: !terminalMouseHasDisplay, "Ghostty requires an active display"))
|
||||
@Suite(
|
||||
.requiresVisibleWindow, .serialized, .disabled(if: !terminalMouseHasDisplay, "Ghostty requires an active display"))
|
||||
@MainActor
|
||||
struct TerminalMouseInteractionTests {
|
||||
@Test func dragCopiesChineseAndMultipleLinesOnlyAfterRelease() async throws {
|
||||
|
||||
@@ -6,7 +6,7 @@ import Testing
|
||||
@testable import Termind
|
||||
@testable import TermindPresentation
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct TerminalSettingsRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"], ["", "Menlo"])
|
||||
func terminalSettingsRenderInSupportedLanguages(_ language: String, family: String) async throws {
|
||||
|
||||
@@ -7,7 +7,9 @@ import Testing
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.enabled(if: ProcessInfo.processInfo.environment["TERMIND_SSH_FIXTURE"] != nil), .serialized)
|
||||
@Suite(
|
||||
.requiresVisibleWindow, .enabled(if: ProcessInfo.processInfo.environment["TERMIND_SSH_FIXTURE"] != nil), .serialized
|
||||
)
|
||||
@MainActor
|
||||
struct TerminalUploadNoticeTests {
|
||||
@Test(arguments: ["kbd", "none"])
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
import Foundation
|
||||
import Testing
|
||||
|
||||
extension Trait where Self == ConditionTrait {
|
||||
/// Window presentation and focus changes require an explicit opt-in, even on a machine with a display.
|
||||
static var requiresVisibleWindow: Self {
|
||||
.enabled(
|
||||
if: ProcessInfo.processInfo.environment["TERMIND_WINDOW_TESTS"] == "1",
|
||||
"Set TERMIND_WINDOW_TESTS=1 to run tests that show windows or take focus"
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -6,7 +6,7 @@ import Testing
|
||||
|
||||
@testable import Termind
|
||||
|
||||
@Suite(.serialized) @MainActor
|
||||
@Suite(.requiresVisibleWindow, .serialized) @MainActor
|
||||
struct WelcomeQuickConnectRenderingTests {
|
||||
@Test(arguments: ["en", "zh-Hans", "zh-Hant"])
|
||||
func welcomePreviewsCommandsAndRejectsRemoteCommands(_ language: String) async throws {
|
||||
|
||||
Reference in new issue
Block a user