import AppKit import ConjureKit import Testing @testable import Conjure @Test @MainActor func popupBackgroundMatchesWindowGradientAcrossTransitions() throws { _ = NSApplication.shared let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 750, height: 480), styleMask: .borderless, backing: .buffered, defer: false) window.isReleasedWhenClosed = false let host = try #require(window.contentView) let reference = LauncherBackground(frame: host.bounds) host.addSubview(reference) let footer = NSView(frame: NSRect(x: 500, y: 8, width: 230, height: 36)) let header = NSView(frame: NSRect(x: 500, y: 420, width: 230, height: 36)) let actionButton = NSButton(frame: footer.bounds) let providerButton = NSButton(frame: header.bounds) footer.addSubview(actionButton) header.addSubview(providerButton) host.addSubview(footer) host.addSubview(header) let actions = ApplicationActionsController() defer { actions.close(animated: false); window.orderOut(nil) } func descendants(_ view: NSView) -> [NSView] { [view] + view.subviews.flatMap(descendants) } func snapshot(_ view: NSView) throws -> NSBitmapImageRep { let bitmap = try #require(view.bitmapImageRepForCachingDisplay(in: view.bounds)) view.cacheDisplay(in: view.bounds, to: bitmap) return bitmap } func color(_ bitmap: NSBitmapImageRep, at point: NSPoint, in view: NSView) throws -> NSColor { let x = Int(point.x * CGFloat(bitmap.pixelsWide) / view.bounds.width) let y = bitmap.pixelsHigh - 1 - Int(point.y * CGFloat(bitmap.pixelsHigh) / view.bounds.height) return try #require(bitmap.colorAt(x: x, y: y)?.usingColorSpace(.deviceRGB)) } for animatedClose in [false, true] { actions.showTranslation(relativeTo: actionButton) actions.close(animated: animatedClose) actions.showProviders(selectedOpenAI: true, relativeTo: providerButton) let background = try #require(descendants(actions.view).compactMap { $0 as? LauncherBackground }.first) let actual = try snapshot(background) let expected = try snapshot(reference) // Sample the title strip and the body, away from text and selection rows. for y in [background.bounds.height - 8, background.bounds.height / 2, 8] { let point = NSPoint(x: 8, y: y) let actualColor = try color(actual, at: point, in: background) let expectedColor = try color(expected, at: background.convert(point, to: reference), in: reference) #expect(abs(actualColor.redComponent - expectedColor.redComponent) < 0.02) #expect(abs(actualColor.greenComponent - expectedColor.greenComponent) < 0.02) #expect(abs(actualColor.blueComponent - expectedColor.blueComponent) < 0.02) #expect(abs(actualColor.alphaComponent - expectedColor.alphaComponent) < 0.02) } actions.close(animated: false) } } @Test @MainActor func providerPickerReplacesAnchorDownwardAndKeepsCurrentSelection() throws { _ = NSApplication.shared let window = NSWindow(contentRect: NSRect(x: 0, y: 0, width: 750, height: 480), styleMask: .borderless, backing: .buffered, defer: false) window.isReleasedWhenClosed = false let host = try #require(window.contentView) let pill = NSView(frame: NSRect(x: 500, y: 420, width: 230, height: 36)) let anchor = NSButton(frame: pill.bounds) pill.addSubview(anchor) host.addSubview(pill) let popup = ApplicationActionsController() defer { popup.close(animated: false); window.orderOut(nil) } var selections: [Bool] = [] popup.selectProvider = { selections.append($0) } popup.showProviders(selectedOpenAI: true, relativeTo: anchor) let rect = popup.view.convert(popup.view.bounds, to: host) #expect(rect.maxY == pill.frame.maxY) #expect(rect.minY < pill.frame.minY) #expect(rect.maxX == pill.frame.maxX) #expect(pill.isAccessibilityHidden()) _ = popup.handle(#selector(NSResponder.insertNewline(_:))) #expect(selections == [true]) // Reopen during the close animation, then switch modes without retaining the old anchor. popup.showTranslation(relativeTo: anchor) popup.showProviders(selectedOpenAI: false, relativeTo: anchor) #expect(popup.view.convert(popup.view.bounds, to: host).maxY == pill.frame.maxY) popup.moveSelection(by: 1) _ = popup.handle(#selector(NSResponder.insertNewline(_:))) #expect(selections == [true, true]) popup.close(animated: false) #expect(pill.alphaValue == 1) #expect(!pill.isAccessibilityHidden()) }