@@ -14,6 +14,10 @@ import SimulatorStatusMagiciOS
1414public class STKSolo : NSObject {
1515 public var animationSpeed : Float = 1.0
1616 public var timeToWaitForever : Double = 20
17+ static var isSingleTestRunning : Bool = {
18+ return isSingleTestRun ( )
19+ } ( )
20+
1721 var internalTimeToWaitForever : Double {
1822 var time = timeToWaitForever
1923 if isUserJenkinsOrHudson ( ) {
@@ -83,6 +87,15 @@ public class STKSolo: NSObject {
8387 self . window = nil
8488 }
8589
90+ func waitRunLoops( timeBetweenChecks: TimeInterval ) {
91+ RunLoop . current. run ( mode: . default, before: Date ( timeIntervalSinceNow: timeBetweenChecks / 3.0 ) )
92+ RunLoop . current. run ( mode: . common, before: Date ( timeIntervalSinceNow: timeBetweenChecks / 3.0 ) )
93+ RunLoop . current. run ( mode: . tracking, before: Date ( timeIntervalSinceNow: timeBetweenChecks / 3.0 ) )
94+ if !STKSolo. isSingleTestRunning {
95+ CATransaction . flush ( ) // prevents animations
96+ }
97+ }
98+
8699 func waitClosureToReturnTrue( _ closure: ( ) -> Bool ,
87100 withinTimeout timeout: TimeInterval ,
88101 timeBetweenChecks: TimeInterval ) {
@@ -92,7 +105,7 @@ public class STKSolo: NSObject {
92105 if closure ( ) {
93106 break
94107 }
95- RunLoop . current . run ( mode : . default , before : Date ( timeIntervalSinceNow : timeBetweenChecks) )
108+ waitRunLoops ( timeBetweenChecks : timeBetweenChecks)
96109 now = Date . timeIntervalSinceReferenceDate
97110 } while ( now - start) < timeout
98111 }
@@ -136,8 +149,14 @@ public class STKSolo: NSObject {
136149 let cleanedText = accessibilityCleaned ( text: tappableText)
137150 let element = waitForAccessibilityElement { $0. accessibilityLabel == cleanedText }
138151 if let element = element {
139- if let view = try ? UIAccessibilityElement . viewContaining ( element, tappable: true ) {
152+ var view : UIView ? = nil
153+ waitClosureToReturnTrue ( { ( ) -> Bool in
154+ view = try ? UIAccessibilityElement . viewContaining ( element, tappable: true )
155+ return view != nil
156+ } , withinTimeout: timeoutForWaitForMethods, timeBetweenChecks: timeBetweenChecks)
157+ if let view = view {
140158 testActor. tap ( element, in: view)
159+ waitRunLoops ( timeBetweenChecks: timeBetweenChecks)
141160 } else {
142161 return false
143162 }
@@ -216,45 +235,42 @@ public class STKSolo: NSObject {
216235 #endif
217236}
218237
219- extension STKSolo {
220-
221- func isUserJenkinsOrHudson( ) -> Bool {
222- var username = NSUserName ( )
223- #if targetEnvironment(simulator)
224- if username. isEmpty {
225- let bundlePathComponents = ( Bundle . main. bundlePath as NSString ) . pathComponents
226- if bundlePathComponents. count >= 3 && bundlePathComponents [ 0 ] == " / " && bundlePathComponents [ 1 ] == " Users " {
227- username = bundlePathComponents [ 2 ]
228- }
229- }
230- #endif
231- return username == " hudson " || username == " jenkins "
232- }
233-
234- func isSingleTestRun( ) -> Bool {
235- /*
236- XCTestConfiguration *testConfiguration = [XCTestConfiguration activeTestConfiguration];
237- // KO when running test of only one class (testsToRun is an Array<String> with class/test names, or just class name)
238- return [testConfiguration.testsToRun count] == 1 && [[testConfiguration.testsToRun anyObject] containsString:@"/"];
239- */
240- if let plistPath = ProcessInfo . processInfo. environment [ " XCTestConfigurationFilePath " ] ,
241- let plistBinary = FileManager . default. contents ( atPath: plistPath) ,
242- let unarchivedObject = try ? NSKeyedUnarchiver . unarchiveTopLevelObjectWithData ( plistBinary) ,
243- let object = unarchivedObject as? NSObject ,
244- let testsToRun = object. value ( forKey: " testsToRun " ) as? NSSet ,
245- testsToRun. count == 1 ,
246- let singleTestToRun = testsToRun. anyObject ( ) as? NSString {
247- return singleTestToRun. contains ( " / " )
248- } else {
249- return false
238+ func isUserJenkinsOrHudson( ) -> Bool {
239+ var username = NSUserName ( )
240+ #if targetEnvironment(simulator)
241+ if username. isEmpty {
242+ let bundlePathComponents = ( Bundle . main. bundlePath as NSString ) . pathComponents
243+ if bundlePathComponents. count >= 3 && bundlePathComponents [ 0 ] == " / " && bundlePathComponents [ 1 ] == " Users " {
244+ username = bundlePathComponents [ 2 ]
250245 }
251246 }
252-
253- func isMultipleTestsRun( ) -> Bool {
254- return XCTestSuite . default. testCaseCount > 1
247+ #endif
248+ return username == " hudson " || username == " jenkins "
249+ }
250+
251+ func isSingleTestRun( ) -> Bool {
252+ /*
253+ XCTestConfiguration *testConfiguration = [XCTestConfiguration activeTestConfiguration];
254+ // KO when running test of only one class (testsToRun is an Array<String> with class/test names, or just class name)
255+ return [testConfiguration.testsToRun count] == 1 && [[testConfiguration.testsToRun anyObject] containsString:@"/"];
256+ */
257+ if let plistPath = ProcessInfo . processInfo. environment [ " XCTestConfigurationFilePath " ] ,
258+ let plistBinary = FileManager . default. contents ( atPath: plistPath) ,
259+ let unarchivedObject = try ? NSKeyedUnarchiver . unarchiveTopLevelObjectWithData ( plistBinary) ,
260+ let object = unarchivedObject as? NSObject ,
261+ let testsToRun = object. value ( forKey: " testsToRun " ) as? NSSet ,
262+ testsToRun. count == 1 ,
263+ let singleTestToRun = testsToRun. anyObject ( ) as? NSString {
264+ return singleTestToRun. contains ( " / " )
265+ } else {
266+ return false
255267 }
256268}
257269
270+ func isMultipleTestsRun( ) -> Bool {
271+ return XCTestSuite . default. testCaseCount > 1
272+ }
273+
258274extension STKSolo : KIFTestActorDelegate {
259275 public func fail( with exception: NSException ! , stopTest stop: Bool ) {
260276 lastExceptions. append ( exception)
0 commit comments