diff --git a/SwiftMonkey/Monkey.swift b/SwiftMonkey/Monkey.swift index 9b3562c..da52c49 100644 --- a/SwiftMonkey/Monkey.swift +++ b/SwiftMonkey/Monkey.swift @@ -7,6 +7,7 @@ // import UIKit +import XCTest /** A general-purpose class for implementing randomised @@ -59,13 +60,15 @@ import UIKit ``` */ public class Monkey { + public typealias ActionClosure = () -> Void + var r: Random let frame: CGRect - var randomActions: [(accumulatedWeight: Double, action: () -> Void)] + var randomActions: [(accumulatedWeight: Double, action: ActionClosure)] var totalWeight: Double - var regularActions: [(interval: Int, action: () -> Void)] + var regularActions: [(interval: Int, action: ActionClosure)] var actionCounter = 0 /** @@ -191,9 +194,9 @@ public class Monkey { - parameter action: The block to run when this event is generated. */ - public func addAction(weight: Double, action: @escaping () -> Void) { + public func addAction(weight: Double, action: @escaping ActionClosure) { totalWeight += weight - randomActions.append((accumulatedWeight: totalWeight, action: action)) + randomActions.append((accumulatedWeight: totalWeight, action: actInForeground(action))) } /** @@ -205,8 +208,32 @@ public class Monkey { - parameter action: The block to run when this event is generated. */ - public func addAction(interval: Int, action: @escaping () -> Void) { - regularActions.append((interval: interval, action: action)) + public func addAction(interval: Int, action: @escaping ActionClosure) { + regularActions.append((interval: interval, action: actInForeground(action))) + } + + /** + Wrap your action with this function to make sure your actions are dispatched inside the app under test + and not in some other app that the Monkey randomly opened. + */ + func actInForeground(_ action: @escaping ActionClosure) -> ActionClosure { + return { + guard #available(iOS 9.0, *) else { + action() + return + } + let closure: ActionClosure = { + if XCUIApplication().state != .runningForeground { + XCUIApplication().activate() + } + action() + } + if Thread.isMainThread { + closure() + } else { + DispatchQueue.main.async(execute: closure) + } + } } /**