From ef453fdc8a836152421b239aece43aaab62bf2a0 Mon Sep 17 00:00:00 2001 From: Soc Sieng Date: Fri, 6 Oct 2023 11:08:45 +1100 Subject: [PATCH] feat: Add support for sending keys to an application without activation For #67 --- .github/workflows/build.yml | 4 +- README.md | 21 ++- Sources/SendKeysLib/AppActivator.swift | 18 ++- .../SendKeysLib/Commands/CommandFactory.swift | 6 +- .../Commands/CommandsIterator.swift | 2 +- .../Commands/CommandsProcessor.swift | 9 +- Sources/SendKeysLib/KeyPresser.swift | 27 +++- Sources/SendKeysLib/MouseController.swift | 5 +- Sources/SendKeysLib/MousePosition.swift | 3 +- Sources/SendKeysLib/Sender.swift | 28 +++- .../SendKeysTests/CommandIteratorTests.swift | 123 ++++++++++-------- .../CommandsProcessorTests.swift | 3 +- 12 files changed, 164 insertions(+), 85 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f9c755f..cfce1c1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -72,7 +72,7 @@ jobs: DEVELOPER_DIR: /Applications/Xcode_${{ matrix.xcode }}.app/Contents/Developer macos_arm64: - runs-on: [self-hosted, macOS, X64] + runs-on: macos-13-large name: macOS Big Sur arm64 @@ -198,7 +198,7 @@ jobs: needs: - create_release - runs-on: [self-hosted, macOS, X64] + runs-on: macos-13-large if: ${{ needs.create_release.outputs.release_created }} name: Create bottle Big Sur (arm64) diff --git a/README.md b/README.md index 3cfd791..27fdd29 100644 --- a/README.md +++ b/README.md @@ -38,10 +38,23 @@ cat example.txt | sendkeys --application-name "Notes" _Activates the Notes application and sends keystrokes piped from `stdout` of the preceding command._ -Note that a list of applications that can be used in `--application-name` can be found using the -[`apps` sub command](#list-of-applications-names). - -Applications can also be activated using the running process id (`--pid` or `-p` option). +### Arguments + +- `--application-name `: The application name to activate or target when sending commands. Note that a + list of applications that can be used in `--application-name` can be found using the + [`apps` sub command](#list-of-applications-names). +- `--pid `: The process id of the application to target when sending commands. Note that this if this + argument is supplied with `--application-name`, `--pid` takes precedence. +- `--targeted`: If supplied, the application keystrokes will only be sent to the targeted application. +- `--no-activate`: If supplied, the specified application will not be activated before sending commands. +- `--input-file `: The path to a file containing the commands to send to the application. +- `--characters `: The characters to send to the application. Note that this argument is ignored if + `--input-file` is supplied. +- `--delay `: The delay between keystrokes and instructions. Defaults to `0.1` seconds. +- `--initial-delay `: The initial delay before sending the first keystroke or instruction. Defaults to + `1` second. +- `--animation-interval `: The time between mouse movements when animating mouse commands. Lower + values results in smoother animations. Defaults to `0.01` seconds. ## Installation diff --git a/Sources/SendKeysLib/AppActivator.swift b/Sources/SendKeysLib/AppActivator.swift index 07dfe95..fb7be49 100644 --- a/Sources/SendKeysLib/AppActivator.swift +++ b/Sources/SendKeysLib/AppActivator.swift @@ -10,7 +10,7 @@ class AppActivator: NSObject { self.processId = processId } - func activate() throws { + func find() throws -> NSRunningApplication? { let apps = NSWorkspace.shared.runningApplications.filter({ a in return a.activationPolicy == .regular }) @@ -61,12 +61,18 @@ class AppActivator: NSObject { return bundleMatch != nil }).first } + } - if app == nil { - throw RuntimeError( - "Application \(appName!) cannot be activated. Run `sendkeys apps` to see a list of applications that can be activated." - ) - } + return app + } + + func activate() throws { + let app = try self.find() + + if app == nil { + throw RuntimeError( + "Application \(appName!) cannot be activated. Run `sendkeys apps` to see a list of applications that can be activated." + ) } if app != nil { diff --git a/Sources/SendKeysLib/Commands/CommandFactory.swift b/Sources/SendKeysLib/Commands/CommandFactory.swift index 975956e..6157ead 100644 --- a/Sources/SendKeysLib/Commands/CommandFactory.swift +++ b/Sources/SendKeysLib/Commands/CommandFactory.swift @@ -26,8 +26,10 @@ public class CommandFactory { self.mouseController = mouseController } - convenience public init() { - self.init(keyPresser: KeyPresser(), mouseController: MouseController(animationRefreshInterval: 0.01)) + convenience public init(keyPresser: KeyPresser) { + self.init( + keyPresser: keyPresser, + mouseController: MouseController(animationRefreshInterval: 0.01, keyPresser: keyPresser)) } public func create(_ commandType: Command.Type, arguments: [String?]) -> Command { diff --git a/Sources/SendKeysLib/Commands/CommandsIterator.swift b/Sources/SendKeysLib/Commands/CommandsIterator.swift index 366a9fc..a12a4f9 100644 --- a/Sources/SendKeysLib/Commands/CommandsIterator.swift +++ b/Sources/SendKeysLib/Commands/CommandsIterator.swift @@ -8,7 +8,7 @@ public class CommandsIterator: IteratorProtocol { var index = 0 - public init(_ commandString: String, commandFactory: CommandFactory = CommandFactory()) { + public init(_ commandString: String, commandFactory: CommandFactory) { self.commandString = commandString self.commandFactory = commandFactory } diff --git a/Sources/SendKeysLib/Commands/CommandsProcessor.swift b/Sources/SendKeysLib/Commands/CommandsProcessor.swift index 7a14160..75e60ce 100644 --- a/Sources/SendKeysLib/Commands/CommandsProcessor.swift +++ b/Sources/SendKeysLib/Commands/CommandsProcessor.swift @@ -22,10 +22,13 @@ public class CommandsProcessor { numberFormatter.maximumSignificantDigits = 3 } - convenience public init(defaultPause: Double, commandExecutor: CommandExecutorProtocol? = nil) { + convenience public init( + defaultPause: Double, keyPresser: KeyPresser, commandExecutor: CommandExecutorProtocol? = nil + ) { self.init( - defaultPause: defaultPause, keyPresser: KeyPresser(), - mouseController: MouseController(animationRefreshInterval: 0.01), commandExecutor: commandExecutor) + defaultPause: defaultPause, keyPresser: keyPresser, + mouseController: MouseController(animationRefreshInterval: 0.01, keyPresser: keyPresser), + commandExecutor: commandExecutor) } private func getDefaultPauseCommand() -> Command { diff --git a/Sources/SendKeysLib/KeyPresser.swift b/Sources/SendKeysLib/KeyPresser.swift index 7c2a7f0..663116b 100644 --- a/Sources/SendKeysLib/KeyPresser.swift +++ b/Sources/SendKeysLib/KeyPresser.swift @@ -1,7 +1,13 @@ import Cocoa import Foundation -class KeyPresser { +public class KeyPresser { + private var application: NSRunningApplication? + + init(app: NSRunningApplication?) { + self.application = app + } + func keyPress(key: String, modifiers: [String]) throws { if let keyDownEvent = try! keyDown(key: key, modifiers: modifiers) { let _ = keyUp(event: keyDownEvent) @@ -11,7 +17,11 @@ class KeyPresser { func keyDown(key: String, modifiers: [String]) throws -> CGEvent? { let keyDownEvent = try! createKeyEvent(key: key, modifiers: modifiers, keyDown: true) - keyDownEvent?.post(tap: CGEventTapLocation.cghidEventTap) + if self.application == nil { + keyDownEvent?.post(tap: CGEventTapLocation.cghidEventTap) + } else { + keyDownEvent?.postToPid(self.application!.processIdentifier) + } return keyDownEvent } @@ -19,7 +29,11 @@ class KeyPresser { func keyUp(key: String, modifiers: [String]) throws -> CGEvent? { let keyUpEvent = try! createKeyEvent(key: key, modifiers: modifiers, keyDown: false) - keyUpEvent?.post(tap: CGEventTapLocation.cghidEventTap) + if self.application == nil { + keyUpEvent?.post(tap: CGEventTapLocation.cghidEventTap) + } else { + keyUpEvent?.postToPid(self.application!.processIdentifier) + } return keyUpEvent } @@ -27,7 +41,12 @@ class KeyPresser { func keyUp(event: CGEvent) -> CGEvent? { let keyCode = UInt16(event.getIntegerValueField(.keyboardEventKeycode)) let keyUpEvent = CGEvent(keyboardEventSource: CGEventSource(event: event), virtualKey: keyCode, keyDown: false) - keyUpEvent?.post(tap: CGEventTapLocation.cghidEventTap) + + if self.application == nil { + keyUpEvent?.post(tap: CGEventTapLocation.cghidEventTap) + } else { + keyUpEvent?.postToPid(self.application!.processIdentifier) + } return keyUpEvent } diff --git a/Sources/SendKeysLib/MouseController.swift b/Sources/SendKeysLib/MouseController.swift index 73aded0..377c67c 100644 --- a/Sources/SendKeysLib/MouseController.swift +++ b/Sources/SendKeysLib/MouseController.swift @@ -15,11 +15,12 @@ class MouseController { } let animationRefreshInterval: TimeInterval - let keyPresser = KeyPresser() + let keyPresser: KeyPresser var downButtons = Set() - init(animationRefreshInterval: TimeInterval) { + init(animationRefreshInterval: TimeInterval, keyPresser: KeyPresser) { self.animationRefreshInterval = animationRefreshInterval + self.keyPresser = keyPresser } func move(start: CGPoint?, end: CGPoint, duration: TimeInterval, flags: CGEventFlags) { diff --git a/Sources/SendKeysLib/MousePosition.swift b/Sources/SendKeysLib/MousePosition.swift index fc42180..e744ad7 100644 --- a/Sources/SendKeysLib/MousePosition.swift +++ b/Sources/SendKeysLib/MousePosition.swift @@ -50,7 +50,8 @@ class MousePosition: ParsableCommand { func printMousePosition(_ position: CGPoint?) { let numberFormatter = Self.createNumberFormatter() - let location = position ?? MouseController(animationRefreshInterval: 0.01).getLocation()! + let location = + position ?? MouseController(animationRefreshInterval: 0.01, keyPresser: KeyPresser(app: nil)).getLocation()! printAndFlush("\(numberFormatter.string(for: location.x)!),\(numberFormatter.string(for: location.y)!)") } diff --git a/Sources/SendKeysLib/Sender.swift b/Sources/SendKeysLib/Sender.swift index f50abab..086aede 100644 --- a/Sources/SendKeysLib/Sender.swift +++ b/Sources/SendKeysLib/Sender.swift @@ -17,6 +17,14 @@ public struct Sender: ParsableCommand { help: "Process id of a running application to send keys to.") var processId: Int? + @Flag( + name: .long, inversion: FlagInversion.prefixedNo, + help: "Activate the specified app or process before sending commands.") + var activate: Bool = true + + @Flag(name: .long, help: "Only send keystrokes to the targeted app or process.") + var targeted: Bool = false + @Option(name: .shortAndLong, help: "Default delay between keystrokes in seconds.") var delay: Double = 0.1 @@ -44,8 +52,20 @@ public struct Sender: ParsableCommand { stderr) } - let keyPresser = KeyPresser() - let mouseController = MouseController(animationRefreshInterval: animationInterval) + let activator = AppActivator(appName: applicationName, processId: processId) + let app: NSRunningApplication? = try activator.find() + let keyPresser: KeyPresser + + if targeted { + if app == nil { + throw RuntimeError("Application could not be found.") + } + keyPresser = KeyPresser(app: app) + } else { + keyPresser = KeyPresser(app: nil) + } + + let mouseController = MouseController(animationRefreshInterval: animationInterval, keyPresser: keyPresser) let commandProcessor = CommandsProcessor( defaultPause: delay, keyPresser: keyPresser, mouseController: mouseController) var commandString: String? @@ -60,7 +80,9 @@ public struct Sender: ParsableCommand { commandString = characters } - try AppActivator(appName: applicationName, processId: processId).activate() + if activate { + try activator.activate() + } if initialDelay > 0 { Sleeper.sleep(seconds: initialDelay) diff --git a/Tests/SendKeysTests/CommandIteratorTests.swift b/Tests/SendKeysTests/CommandIteratorTests.swift index 0ab72cc..fecafd6 100644 --- a/Tests/SendKeysTests/CommandIteratorTests.swift +++ b/Tests/SendKeysTests/CommandIteratorTests.swift @@ -3,8 +3,17 @@ import XCTest @testable import SendKeysLib final class CommandIteratorTests: XCTestCase { + var commandFactory: CommandFactory! + + override func setUp() { + let keyPresser = KeyPresser(app: nil) + commandFactory = CommandFactory( + keyPresser: keyPresser, + mouseController: MouseController(animationRefreshInterval: 0.01, keyPresser: keyPresser)) + } + func testParsesCharacters() throws { - let commands = getCommands(CommandsIterator("abc")) + let commands = getCommands(CommandsIterator("abc", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -15,7 +24,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyPress() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -24,7 +33,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyPressDelete() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -33,7 +42,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyPressesWithModifierKey() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -42,7 +51,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyPressesWithModifierKeys() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -51,7 +60,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyPressAlias() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -60,7 +69,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyDown() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -69,7 +78,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyDownWithModifierKey() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -78,7 +87,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyDownAsModifierKey() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -87,7 +96,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyUp() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -96,7 +105,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyUpWithModifierKey() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -105,7 +114,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesKeyUpAsModifierKey() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -114,7 +123,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesNewLines() throws { - let commands = getCommands(CommandsIterator("\n\n\n")) + let commands = getCommands(CommandsIterator("\n\n\n", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -125,7 +134,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesNewLinesWithCarriageReturns() throws { - let commands = getCommands(CommandsIterator("\r\n\r\n\n")) + let commands = getCommands(CommandsIterator("\r\n\r\n\n", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -136,7 +145,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMultipleKeyPresses() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -146,7 +155,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesContinuation() throws { - let commands = getCommands(CommandsIterator("<\\>")) + let commands = getCommands(CommandsIterator("<\\>", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -155,7 +164,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesPause() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -164,7 +173,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesStickyPause() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -173,7 +182,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseMove() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -182,7 +191,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseMoveWithModifier() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -191,7 +200,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseMoveWithDuration() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -200,7 +209,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseMoveWithNegativeCoordinates() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -209,7 +218,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseMoveWithDurationAndModifiers() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -218,7 +227,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesPartialMouseMove() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -227,7 +236,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesPartialMouseMoveWithDuration() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -236,7 +245,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseClick() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -245,7 +254,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseClickWithModifiers() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -254,7 +263,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseClickWithClickCount() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -263,7 +272,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseClickWithModifiersAndClickCount() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -272,7 +281,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMousePath() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -282,7 +291,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMousePathWithOffset() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -292,7 +301,8 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMousePathWithOffsetAndScale() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands( + CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -302,7 +312,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMousePathWithOffsetAndPartialScale() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -312,7 +322,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDrag() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -321,7 +331,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDragWithButton() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -330,7 +340,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDragWithButtonAndModifiers() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -340,7 +350,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDragWithDuration() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -349,7 +359,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDragWithDurationWithNegativeCoordinates() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -358,7 +368,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDragWithDurationAndButton() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -367,7 +377,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDragWithDurationAndButtonAndModifier() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -376,7 +386,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesPartialMouseDrag() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -385,7 +395,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesPartialMouseDragWithDuration() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -394,7 +404,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesPartialMouseDragWithDurationAndButton() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -403,7 +413,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseScroll() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -412,7 +422,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseScrollWithNegativeAmount() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -421,7 +431,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseScrollWithDuration() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -430,7 +440,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseScrollWithDurationAndModifiers() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -439,7 +449,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseScrollWithNegativeAmountAndDuration() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -448,7 +458,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDown() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -457,7 +467,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseDownWithModifiers() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -466,7 +476,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseUp() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -475,7 +485,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseUpWithModifiers() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -484,7 +494,8 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseFocus() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands( + CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -493,7 +504,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseFocusWithSingleRadius() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -502,7 +513,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseFocusWithNegativeCoordinates() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ @@ -511,7 +522,7 @@ final class CommandIteratorTests: XCTestCase { } func testParsesMouseFocusWithNegativeAngles() throws { - let commands = getCommands(CommandsIterator("")) + let commands = getCommands(CommandsIterator("", commandFactory: commandFactory)) XCTAssertEqual( commands, [ diff --git a/Tests/SendKeysTests/CommandsProcessorTests.swift b/Tests/SendKeysTests/CommandsProcessorTests.swift index 8e2856d..5e9ab03 100644 --- a/Tests/SendKeysTests/CommandsProcessorTests.swift +++ b/Tests/SendKeysTests/CommandsProcessorTests.swift @@ -16,7 +16,8 @@ final class CommandProcessorTests: XCTestCase { override func setUp() { commandExecutor = CommandExecutorSpy() - commandsProcessor = CommandsProcessor(defaultPause: 0.1, commandExecutor: commandExecutor) + commandsProcessor = CommandsProcessor( + defaultPause: 0.1, keyPresser: KeyPresser(app: nil), commandExecutor: commandExecutor) } func testExecutesSingleKeyPress() {