Send notify regression input via workspace socket
This commit is contained in:
parent
6c163b1eb0
commit
e6e5a57dd6
3 changed files with 56 additions and 10 deletions
|
|
@ -5750,9 +5750,6 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
|
|||
"expectedLatestWindowId": window1.windowId.uuidString,
|
||||
"expectedLatestTabId": tabId1.uuidString,
|
||||
], at: path)
|
||||
// Leave the initial window's terminal focused so UI tests can type shell
|
||||
// commands while still keeping the second window configured for notifications.
|
||||
window1.window?.makeKeyAndOrderFront(nil)
|
||||
self.publishMultiWindowNotificationSocketStateIfNeeded(at: path)
|
||||
}
|
||||
}
|
||||
|
|
@ -5821,7 +5818,7 @@ final class AppDelegate: NSObject, NSApplicationDelegate, UNUserNotificationCent
|
|||
"socketPathExists": health.socketPathExists ? "1" : "0",
|
||||
"socketFailureSignals": failureSignals,
|
||||
], at: dataPath)
|
||||
guard !isTimedOut else { return }
|
||||
guard !isTimedOut, !isReady else { return }
|
||||
DispatchQueue.main.asyncAfter(deadline: .now() + 0.05) {
|
||||
publish()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1247,6 +1247,9 @@ class TerminalController {
|
|||
case "send_key":
|
||||
return sendKey(args)
|
||||
|
||||
case "send_workspace":
|
||||
return sendInputToWorkspace(args)
|
||||
|
||||
case "send_surface":
|
||||
return sendInputToSurface(args)
|
||||
|
||||
|
|
@ -9267,6 +9270,7 @@ class TerminalController {
|
|||
Input commands:
|
||||
send <text> - Send text to current terminal
|
||||
send_key <key> - Send special key (ctrl-c, ctrl-d, enter, tab, escape)
|
||||
send_workspace <workspace_id> <text> - Send text to a workspace's focused terminal
|
||||
send_surface <id|idx> <text> - Send text to a specific terminal
|
||||
send_key_surface <id|idx> <key> - Send special key to a specific terminal
|
||||
read_screen [id|idx] [--scrollback] [--lines N] - Read terminal text (plain text)
|
||||
|
|
@ -11594,6 +11598,49 @@ class TerminalController {
|
|||
return success ? "OK" : "ERROR: Failed to send input"
|
||||
}
|
||||
|
||||
private func sendInputToWorkspace(_ args: String) -> String {
|
||||
guard let tabManager else { return "ERROR: TabManager not available" }
|
||||
let parts = args.split(separator: " ", maxSplits: 1).map(String.init)
|
||||
guard parts.count == 2 else { return "ERROR: Usage: send_workspace <workspace_id> <text>" }
|
||||
|
||||
let workspaceArg = parts[0].trimmingCharacters(in: .whitespacesAndNewlines)
|
||||
let text = parts[1]
|
||||
guard let workspaceId = UUID(uuidString: workspaceArg) else {
|
||||
return "ERROR: Invalid workspace ID"
|
||||
}
|
||||
|
||||
var success = false
|
||||
var error: String?
|
||||
DispatchQueue.main.sync {
|
||||
guard let targetManager = AppDelegate.shared?.tabManagerFor(tabId: workspaceId)
|
||||
?? (tabManager.tabs.contains(where: { $0.id == workspaceId }) ? tabManager : nil) else {
|
||||
error = "ERROR: Workspace not found"
|
||||
return
|
||||
}
|
||||
guard let tab = targetManager.tabs.first(where: { $0.id == workspaceId }),
|
||||
let terminalPanel = tab.focusedTerminalPanel else {
|
||||
error = "ERROR: No focused terminal in workspace"
|
||||
return
|
||||
}
|
||||
|
||||
let unescaped = text
|
||||
.replacingOccurrences(of: "\\n", with: "\r")
|
||||
.replacingOccurrences(of: "\\r", with: "\r")
|
||||
.replacingOccurrences(of: "\\t", with: "\t")
|
||||
|
||||
if let surface = terminalPanel.surface.surface {
|
||||
sendSocketText(unescaped, surface: surface)
|
||||
} else {
|
||||
terminalPanel.sendText(unescaped)
|
||||
terminalPanel.surface.requestBackgroundSurfaceStartIfNeeded()
|
||||
}
|
||||
success = true
|
||||
}
|
||||
|
||||
if let error { return error }
|
||||
return success ? "OK" : "ERROR: Failed to send input"
|
||||
}
|
||||
|
||||
private func sendInputToSurface(_ args: String) -> String {
|
||||
guard let tabManager = tabManager else { return "ERROR: TabManager not available" }
|
||||
let parts = args.split(separator: " ", maxSplits: 1).map(String.init)
|
||||
|
|
|
|||
|
|
@ -224,6 +224,10 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
XCTFail("Missing setup workspace id")
|
||||
return
|
||||
}
|
||||
guard let tabId1 = setup["tabId1"], !tabId1.isEmpty else {
|
||||
XCTFail("Missing source workspace id")
|
||||
return
|
||||
}
|
||||
if let expectedSocketPath = setup["socketExpectedPath"], !expectedSocketPath.isEmpty {
|
||||
socketPath = expectedSocketPath
|
||||
}
|
||||
|
|
@ -270,11 +274,6 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
return
|
||||
}
|
||||
|
||||
XCTAssertTrue(app.windows.element(boundBy: 0).waitForExistence(timeout: 4.0), "Expected at least one window before typing notify command")
|
||||
app.windows.element(boundBy: 0)
|
||||
.coordinate(withNormalizedOffset: CGVector(dx: 0.5, dy: 0.5))
|
||||
.click()
|
||||
|
||||
let notifyCommand = [
|
||||
"rm -f \(shellSingleQuote(commandStatusPath)) \(shellSingleQuote(commandStdoutPath)) \(shellSingleQuote(commandStderrPath));",
|
||||
"(sleep 1;",
|
||||
|
|
@ -290,7 +289,10 @@ final class MultiWindowNotificationsUITests: XCTestCase {
|
|||
"2>\(shellSingleQuote(commandStderrPath));",
|
||||
"printf '%s' $? >\(shellSingleQuote(commandStatusPath))) >/dev/null 2>&1 &"
|
||||
].joined(separator: " ")
|
||||
app.typeText(notifyCommand + "\n")
|
||||
guard socketCommand("send_workspace \(tabId1) \(notifyCommand)\\n") == "OK" else {
|
||||
XCTFail("Failed to inject delayed bundled `cmux notify` command into source workspace \(tabId1)")
|
||||
return
|
||||
}
|
||||
|
||||
let finder = XCUIApplication(bundleIdentifier: "com.apple.finder")
|
||||
finder.activate()
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue