Peekaboo/peekaboo-cli/Tests/peekabooTests/WindowManagerTests.swift
Peter Steinberger 92d3bdb1f7 Fix WindowManagerTests to use return instead of XCTSkip
- Replace XCTSkip with simple return for non-running apps
- This avoids dependency on XCTest framework in Swift Testing

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-06-08 11:24:01 +01:00

289 lines
10 KiB
Swift

import AppKit
@testable import peekaboo
import Testing
@Suite("WindowManager Tests", .tags(.windowManager, .unit))
struct WindowManagerTests {
// MARK: - Get Windows For App Tests
@Test("Getting windows for Finder app", .tags(.integration))
func getWindowsForFinderApp() throws {
// Get Finder's PID
let apps = NSWorkspace.shared.runningApplications
let finder = try #require(apps.first { $0.bundleIdentifier == "com.apple.finder" })
// Test getting windows for Finder
let windows = try WindowManager.getWindowsForApp(pid: finder.processIdentifier)
// Finder usually has at least one window
// Windows count is always non-negative
// If there are windows, verify they're sorted by index
if windows.count > 1 {
for index in 1..<windows.count {
#expect(windows[index].windowIndex >= windows[index - 1].windowIndex)
}
}
}
@Test("Getting windows for non-existent app returns empty array", .tags(.fast))
func getWindowsForNonExistentApp() throws {
// Test with non-existent PID
let windows = try WindowManager.getWindowsForApp(pid: 99999)
// Should return empty array, not throw
#expect(windows.isEmpty)
}
@Test("Off-screen window filtering works correctly", .tags(.integration))
func getWindowsWithOffScreenOption() throws {
// Get Finder's PID for testing
let apps = NSWorkspace.shared.runningApplications
let finder = try #require(apps.first { $0.bundleIdentifier == "com.apple.finder" })
// Test with includeOffScreen = true
let allWindows = try WindowManager.getWindowsForApp(pid: finder.processIdentifier, includeOffScreen: true)
// Test with includeOffScreen = false (default)
let onScreenWindows = try WindowManager.getWindowsForApp(pid: finder.processIdentifier, includeOffScreen: false)
// All windows should include off-screen ones, so count should be >= on-screen only
#expect(allWindows.count >= onScreenWindows.count)
}
// MARK: - WindowData Structure Tests
@Test("WindowData has all required properties", .tags(.fast))
func windowDataStructure() throws {
// Get any app's windows to test the structure
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
guard let app = apps.first else {
return // Skip test if no regular apps running
}
let windows = try WindowManager.getWindowsForApp(pid: app.processIdentifier)
// If we have windows, verify WindowData properties
if let firstWindow = windows.first {
// Check required properties exist
#expect(firstWindow.windowId > 0)
#expect(firstWindow.windowIndex >= 0)
#expect(!firstWindow.title.isEmpty)
#expect(firstWindow.bounds.width >= 0)
#expect(firstWindow.bounds.height >= 0)
}
}
// MARK: - Window Info Tests
@Test("Getting window info with details", .tags(.integration))
func getWindowsInfoForApp() throws {
// Test getting window info with details
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
guard let app = apps.first else {
return // Skip test if no regular apps running
}
let windowInfos = try WindowManager.getWindowsInfoForApp(
pid: app.processIdentifier,
includeOffScreen: false,
includeBounds: true,
includeIDs: true
)
// Verify WindowInfo structure
if let firstInfo = windowInfos.first {
#expect(!firstInfo.window_title.isEmpty)
#expect(firstInfo.window_id != nil)
#expect(firstInfo.bounds != nil)
}
}
// MARK: - Parameterized Tests
@Test(
"Window retrieval with various options",
arguments: [
(includeOffScreen: true, includeBounds: true, includeIDs: true),
(includeOffScreen: false, includeBounds: true, includeIDs: true),
(includeOffScreen: true, includeBounds: false, includeIDs: true),
(includeOffScreen: true, includeBounds: true, includeIDs: false)
]
)
func windowRetrievalOptions(includeOffScreen: Bool, includeBounds: Bool, includeIDs: Bool) throws {
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
guard let app = apps.first else {
return // Skip test if no regular apps running
}
let windowInfos = try WindowManager.getWindowsInfoForApp(
pid: app.processIdentifier,
includeOffScreen: includeOffScreen,
includeBounds: includeBounds,
includeIDs: includeIDs
)
// Verify options are respected
for info in windowInfos {
// Note: window_title can be empty for system windows, this is expected
// Just verify the property exists (it's a String, not optional)
if includeIDs {
#expect(info.window_id != nil)
} else {
#expect(info.window_id == nil)
}
if includeBounds {
#expect(info.bounds != nil)
} else {
#expect(info.bounds == nil)
}
}
}
// MARK: - Performance Tests
@Test(
"Window retrieval performance",
arguments: 1...5
)
func getWindowsPerformance(iteration: Int) throws {
// Test performance of getting windows
let apps = NSWorkspace.shared.runningApplications
let finder = try #require(apps.first { $0.bundleIdentifier == "com.apple.finder" })
_ = try WindowManager.getWindowsForApp(pid: finder.processIdentifier)
// Windows count is always non-negative
}
}
// MARK: - Extended Window Manager Tests
@Suite("WindowManager Advanced Tests", .tags(.windowManager, .integration))
struct WindowManagerAdvancedTests {
@Test("Multiple apps window retrieval", .tags(.integration))
func multipleAppsWindows() throws {
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
let appsToTest = apps.prefix(3) // Test first 3 apps
for app in appsToTest {
let windows = try WindowManager.getWindowsForApp(pid: app.processIdentifier)
// Each app should successfully return a window list (even if empty)
// Windows count is always non-negative
// Verify window indices are sequential
for (index, window) in windows.enumerated() {
#expect(window.windowIndex == index)
}
}
}
@Test("Window bounds validation", .tags(.integration))
func windowBoundsValidation() throws {
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
guard let app = apps.first else {
return // Skip test if no regular apps running
}
let windows = try WindowManager.getWindowsForApp(pid: app.processIdentifier)
for window in windows {
// Window bounds should be reasonable
#expect(window.bounds.width > 0)
#expect(window.bounds.height > 0)
#expect(window.bounds.width < 10000) // Reasonable maximum
#expect(window.bounds.height < 10000) // Reasonable maximum
}
}
@Test(
"System apps window detection",
arguments: ["com.apple.finder", "com.apple.dock", "com.apple.systemuiserver"]
)
func systemAppsWindows(bundleId: String) throws {
let apps = NSWorkspace.shared.runningApplications
guard let app = apps.first(where: { $0.bundleIdentifier == bundleId }) else {
// Skip test if app not running - this is acceptable for system apps
return
}
let windows = try WindowManager.getWindowsForApp(pid: app.processIdentifier)
// System apps might have 0 or more windows
// Windows count is always non-negative
// If windows exist, they should have valid properties
for window in windows {
#expect(window.windowId > 0)
#expect(!window.title.isEmpty)
}
}
@Test("Window title encoding", .tags(.fast))
func windowTitleEncoding() throws {
// Test that window titles with special characters are handled
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
for app in apps.prefix(5) {
let windows = try WindowManager.getWindowsForApp(pid: app.processIdentifier)
for window in windows {
// Title should be valid UTF-8
#expect(!window.title.utf8.isEmpty)
// Should handle common special characters
let specialChars = ["", "", "©", "", ""]
// Window titles might contain these, should not crash
for char in specialChars {
_ = window.title.contains(char)
}
}
}
}
@Test("Concurrent window queries", .tags(.integration))
func concurrentWindowQueries() async throws {
let apps = NSWorkspace.shared.runningApplications.filter { $0.activationPolicy == .regular }
guard let app = apps.first else {
return // Skip test if no regular apps running
}
// Test concurrent access to WindowManager
await withTaskGroup(of: Result<[WindowData], Error>.self) { group in
for _ in 0..<5 {
group.addTask {
do {
let windows = try WindowManager.getWindowsForApp(pid: app.processIdentifier)
return .success(windows)
} catch {
return .failure(error)
}
}
}
var results: [Result<[WindowData], Error>] = []
for await result in group {
results.append(result)
}
// All concurrent queries should succeed
#expect(results.count == 5)
for result in results {
switch result {
case .success:
break // Windows count is always non-negative
case let .failure(error):
Issue.record("Concurrent query failed: \(error)")
}
}
}
}
}