mirror of
https://github.com/samsonjs/Peekaboo.git
synced 2026-04-27 15:07:41 +00:00
Convert test to use proper async/await instead of semaphore
- Replace DispatchSemaphore usage in ScreenshotValidationTests with async/await - Make test functions async and use Task.sleep instead of RunLoop/Thread.sleep - Use proper Swift Testing async patterns for better compatibility
This commit is contained in:
parent
fbc478f75e
commit
fafa8fdc2a
1 changed files with 34 additions and 60 deletions
|
|
@ -13,13 +13,13 @@ struct ScreenshotValidationTests {
|
||||||
// MARK: - Image Analysis Tests
|
// MARK: - Image Analysis Tests
|
||||||
|
|
||||||
@Test("Validate screenshot contains expected content", .tags(.imageAnalysis))
|
@Test("Validate screenshot contains expected content", .tags(.imageAnalysis))
|
||||||
func validateScreenshotContent() throws {
|
func validateScreenshotContent() async throws {
|
||||||
// Create a temporary test window with known content
|
// Create a temporary test window with known content
|
||||||
let testWindow = createTestWindow(withContent: .text("PEEKABOO_TEST_12345"))
|
let testWindow = createTestWindow(withContent: .text("PEEKABOO_TEST_12345"))
|
||||||
defer { testWindow.close() }
|
defer { testWindow.close() }
|
||||||
|
|
||||||
// Give window time to render
|
// Give window time to render
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.5))
|
try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
|
||||||
|
|
||||||
// Capture the window
|
// Capture the window
|
||||||
let windowID = CGWindowID(testWindow.windowNumber)
|
let windowID = CGWindowID(testWindow.windowNumber)
|
||||||
|
|
@ -27,7 +27,7 @@ struct ScreenshotValidationTests {
|
||||||
let outputPath = "/tmp/peekaboo-content-test.png"
|
let outputPath = "/tmp/peekaboo-content-test.png"
|
||||||
defer { try? FileManager.default.removeItem(atPath: outputPath) }
|
defer { try? FileManager.default.removeItem(atPath: outputPath) }
|
||||||
|
|
||||||
_ = try captureWindowToFile(windowID: windowID, path: outputPath, format: .png)
|
_ = try await captureWindowToFile(windowID: windowID, path: outputPath, format: .png)
|
||||||
|
|
||||||
// Load and analyze the image
|
// Load and analyze the image
|
||||||
guard let image = NSImage(contentsOfFile: outputPath) else {
|
guard let image = NSImage(contentsOfFile: outputPath) else {
|
||||||
|
|
@ -44,12 +44,12 @@ struct ScreenshotValidationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test("Compare screenshots for visual regression", .tags(.regression))
|
@Test("Compare screenshots for visual regression", .tags(.regression))
|
||||||
func visualRegressionTest() throws {
|
func visualRegressionTest() async throws {
|
||||||
// Create test window with specific visual pattern
|
// Create test window with specific visual pattern
|
||||||
let testWindow = createTestWindow(withContent: .grid)
|
let testWindow = createTestWindow(withContent: .grid)
|
||||||
defer { testWindow.close() }
|
defer { testWindow.close() }
|
||||||
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.5))
|
try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
|
||||||
|
|
||||||
let windowID = CGWindowID(testWindow.windowNumber)
|
let windowID = CGWindowID(testWindow.windowNumber)
|
||||||
|
|
||||||
|
|
@ -61,13 +61,13 @@ struct ScreenshotValidationTests {
|
||||||
try? FileManager.default.removeItem(atPath: currentPath)
|
try? FileManager.default.removeItem(atPath: currentPath)
|
||||||
}
|
}
|
||||||
|
|
||||||
_ = try captureWindowToFile(windowID: windowID, path: baselinePath, format: .png)
|
_ = try await captureWindowToFile(windowID: windowID, path: baselinePath, format: .png)
|
||||||
|
|
||||||
// Make a small change (in real tests, this would be application state change)
|
// Make a small change (in real tests, this would be application state change)
|
||||||
Thread.sleep(forTimeInterval: 0.1)
|
try await Task.sleep(nanoseconds: 100_000_000) // 0.1 seconds
|
||||||
|
|
||||||
// Capture current
|
// Capture current
|
||||||
_ = try captureWindowToFile(windowID: windowID, path: currentPath, format: .png)
|
_ = try await captureWindowToFile(windowID: windowID, path: currentPath, format: .png)
|
||||||
|
|
||||||
// Compare images
|
// Compare images
|
||||||
let baselineImage = NSImage(contentsOfFile: baselinePath)
|
let baselineImage = NSImage(contentsOfFile: baselinePath)
|
||||||
|
|
@ -81,11 +81,11 @@ struct ScreenshotValidationTests {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test("Test different image formats", .tags(.formats))
|
@Test("Test different image formats", .tags(.formats))
|
||||||
func imageFormats() throws {
|
func imageFormats() async throws {
|
||||||
let testWindow = createTestWindow(withContent: .gradient)
|
let testWindow = createTestWindow(withContent: .gradient)
|
||||||
defer { testWindow.close() }
|
defer { testWindow.close() }
|
||||||
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.5))
|
try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
|
||||||
|
|
||||||
let windowID = CGWindowID(testWindow.windowNumber)
|
let windowID = CGWindowID(testWindow.windowNumber)
|
||||||
|
|
||||||
|
|
@ -95,7 +95,7 @@ struct ScreenshotValidationTests {
|
||||||
let path = "/tmp/peekaboo-format-test.\(format.rawValue)"
|
let path = "/tmp/peekaboo-format-test.\(format.rawValue)"
|
||||||
defer { try? FileManager.default.removeItem(atPath: path) }
|
defer { try? FileManager.default.removeItem(atPath: path) }
|
||||||
|
|
||||||
_ = try captureWindowToFile(windowID: windowID, path: path, format: format)
|
_ = try await captureWindowToFile(windowID: windowID, path: path, format: format)
|
||||||
|
|
||||||
#expect(FileManager.default.fileExists(atPath: path))
|
#expect(FileManager.default.fileExists(atPath: path))
|
||||||
|
|
||||||
|
|
@ -151,11 +151,11 @@ struct ScreenshotValidationTests {
|
||||||
// MARK: - Performance Tests
|
// MARK: - Performance Tests
|
||||||
|
|
||||||
@Test("Screenshot capture performance", .tags(.performance))
|
@Test("Screenshot capture performance", .tags(.performance))
|
||||||
func capturePerformance() throws {
|
func capturePerformance() async throws {
|
||||||
let testWindow = createTestWindow(withContent: .solid(.white))
|
let testWindow = createTestWindow(withContent: .solid(.white))
|
||||||
defer { testWindow.close() }
|
defer { testWindow.close() }
|
||||||
|
|
||||||
RunLoop.current.run(until: Date().addingTimeInterval(0.5))
|
try await Task.sleep(nanoseconds: 500_000_000) // 0.5 seconds
|
||||||
|
|
||||||
let windowID = CGWindowID(testWindow.windowNumber)
|
let windowID = CGWindowID(testWindow.windowNumber)
|
||||||
|
|
||||||
|
|
@ -167,7 +167,7 @@ struct ScreenshotValidationTests {
|
||||||
defer { try? FileManager.default.removeItem(atPath: path) }
|
defer { try? FileManager.default.removeItem(atPath: path) }
|
||||||
|
|
||||||
let start = CFAbsoluteTimeGetCurrent()
|
let start = CFAbsoluteTimeGetCurrent()
|
||||||
_ = try captureWindowToFile(windowID: windowID, path: path, format: .png)
|
_ = try await captureWindowToFile(windowID: windowID, path: path, format: .png)
|
||||||
let duration = CFAbsoluteTimeGetCurrent() - start
|
let duration = CFAbsoluteTimeGetCurrent() - start
|
||||||
|
|
||||||
captureTimes.append(duration)
|
captureTimes.append(duration)
|
||||||
|
|
@ -234,9 +234,9 @@ struct ScreenshotValidationTests {
|
||||||
windowID: CGWindowID,
|
windowID: CGWindowID,
|
||||||
path: String,
|
path: String,
|
||||||
format: ImageFormat
|
format: ImageFormat
|
||||||
) throws -> ImageCaptureData {
|
) async throws -> ImageCaptureData {
|
||||||
// Use modern ScreenCaptureKit API instead of deprecated CGWindowListCreateImage
|
// Use modern ScreenCaptureKit API instead of deprecated CGWindowListCreateImage
|
||||||
let image = try captureWindowWithScreenCaptureKit(windowID: windowID)
|
let image = try await captureWindowWithScreenCaptureKit(windowID: windowID)
|
||||||
|
|
||||||
// Save to file
|
// Save to file
|
||||||
let nsImage = NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
|
let nsImage = NSImage(cgImage: image, size: NSSize(width: image.width, height: image.height))
|
||||||
|
|
@ -254,55 +254,29 @@ struct ScreenshotValidationTests {
|
||||||
])
|
])
|
||||||
}
|
}
|
||||||
|
|
||||||
private func captureWindowWithScreenCaptureKit(windowID: CGWindowID) throws -> CGImage {
|
private func captureWindowWithScreenCaptureKit(windowID: CGWindowID) async throws -> CGImage {
|
||||||
// This needs to be async, so we'll use a semaphore to make it synchronous for the test
|
// Get available content
|
||||||
var capturedImage: CGImage?
|
let availableContent = try await SCShareableContent.current
|
||||||
var captureError: Error?
|
|
||||||
let semaphore = DispatchSemaphore(value: 0)
|
|
||||||
|
|
||||||
Task {
|
// Find the window by ID
|
||||||
do {
|
guard let scWindow = availableContent.windows.first(where: { $0.windowID == windowID }) else {
|
||||||
// Get available content
|
throw CaptureError.windowNotFound
|
||||||
let availableContent = try await SCShareableContent.current
|
|
||||||
|
|
||||||
// Find the window by ID
|
|
||||||
guard let scWindow = availableContent.windows.first(where: { $0.windowID == windowID }) else {
|
|
||||||
throw CaptureError.windowNotFound
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create content filter for the specific window
|
|
||||||
let filter = SCContentFilter(desktopIndependentWindow: scWindow)
|
|
||||||
|
|
||||||
// Configure capture settings
|
|
||||||
let configuration = SCStreamConfiguration()
|
|
||||||
configuration.backgroundColor = .clear
|
|
||||||
configuration.shouldBeOpaque = true
|
|
||||||
configuration.showsCursor = false
|
|
||||||
|
|
||||||
// Capture the image
|
|
||||||
let image = try await SCScreenshotManager.captureImage(
|
|
||||||
contentFilter: filter,
|
|
||||||
configuration: configuration
|
|
||||||
)
|
|
||||||
|
|
||||||
capturedImage = image
|
|
||||||
} catch {
|
|
||||||
captureError = error
|
|
||||||
}
|
|
||||||
semaphore.signal()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
semaphore.wait()
|
// Create content filter for the specific window
|
||||||
|
let filter = SCContentFilter(desktopIndependentWindow: scWindow)
|
||||||
|
|
||||||
if let error = captureError {
|
// Configure capture settings
|
||||||
throw error
|
let configuration = SCStreamConfiguration()
|
||||||
}
|
configuration.backgroundColor = .clear
|
||||||
|
configuration.shouldBeOpaque = true
|
||||||
|
configuration.showsCursor = false
|
||||||
|
|
||||||
guard let image = capturedImage else {
|
// Capture the image
|
||||||
throw CaptureError.windowCaptureFailed(nil)
|
return try await SCScreenshotManager.captureImage(
|
||||||
}
|
contentFilter: filter,
|
||||||
|
configuration: configuration
|
||||||
return image
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func captureDisplayToFile(
|
private func captureDisplayToFile(
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue