Skip to content

Commit

Permalink
Fix issue when tapping accessibility element's view not available yet
Browse files Browse the repository at this point in the history
  • Loading branch information
kenji21 committed Jan 4, 2019
1 parent a72a9b8 commit fa2ffbd
Show file tree
Hide file tree
Showing 4 changed files with 80 additions and 40 deletions.
15 changes: 12 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,32 @@ This project adheres to [Semantic Versioning](http://semver.org/).

### Removed

## [0.1.7](https://github.com/openium/SwiftiumTestingKit/compare/latest...HEAD)

## [0.1.8](https://github.com/openium/SwiftiumTestingKit/compare/v0.1.8...HEAD)
### Added

### Changed
Fix issue when tapping accessibility element's view not available yet

### Removed

## [0.1.7](https://github.com/openium/SwiftiumTestingKit/compare/v0.1.7...HEAD)
### Added
Allow pilotable server to specify responses headers for all requests and responses headers for each request

### Changed

### Removed

## [0.1.6](https://github.com/openium/SwiftiumTestingKit/compare/latest...HEAD)
## [0.1.6](https://github.com/openium/SwiftiumTestingKit/compare/v0.1.6...HEAD)
### Added

### Changed
Fixed search for text containing \n

### Removed

## [0.1.5](https://github.com/openium/SwiftiumTestingKit/compare/latest...HEAD)
## [0.1.5](https://github.com/openium/SwiftiumTestingKit/compare/v0.1.5...HEAD)
### Added

### Changed
Expand Down
15 changes: 15 additions & 0 deletions STKTestAppTests/STKSoloTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -174,4 +174,19 @@ class STKSoloTests: XCTestCase {
XCTAssertTrue(waitForCell)
XCTAssertTrue(waitForDeleteConfirmationButton)
}

func testWaitForText_onAlertViewController_shouldFindOKButton() {
// Given
sut.showViewControllerInCleanWindow(viewController)
let alertVC = UIAlertController(title: "title", message: "message", preferredStyle: .alert)
let alertOKAction = UIAlertAction(title: "OK", style: .default, handler: nil)
alertVC.addAction(alertOKAction)
viewController.present(alertVC, animated: false, completion: nil)

// When
let waitForOK = sut.waitFor(tappableText: "OK", andTapIt: true)

// Expect
XCTAssertTrue(waitForOK)
}
}
2 changes: 1 addition & 1 deletion SwiftiumTestingKit/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>0.1.7</string>
<string>0.1.8</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
</dict>
Expand Down
88 changes: 52 additions & 36 deletions SwiftiumTestingKit/STKSolo.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@ import SimulatorStatusMagiciOS
public class STKSolo: NSObject {
public var animationSpeed: Float = 1.0
public var timeToWaitForever: Double = 20
static var isSingleTestRunning: Bool = {
return isSingleTestRun()
}()

var internalTimeToWaitForever: Double {
var time = timeToWaitForever
if isUserJenkinsOrHudson() {
Expand Down Expand Up @@ -83,6 +87,15 @@ public class STKSolo: NSObject {
self.window = nil
}

func waitRunLoops(timeBetweenChecks: TimeInterval) {
RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: timeBetweenChecks / 3.0))
RunLoop.current.run(mode: .common, before: Date(timeIntervalSinceNow: timeBetweenChecks / 3.0))
RunLoop.current.run(mode: .tracking, before: Date(timeIntervalSinceNow: timeBetweenChecks / 3.0))
if !STKSolo.isSingleTestRunning {
CATransaction.flush() // prevents animations
}
}

func waitClosureToReturnTrue(_ closure: () -> Bool,
withinTimeout timeout: TimeInterval,
timeBetweenChecks: TimeInterval) {
Expand All @@ -92,7 +105,7 @@ public class STKSolo: NSObject {
if closure() {
break
}
RunLoop.current.run(mode: .default, before: Date(timeIntervalSinceNow: timeBetweenChecks))
waitRunLoops(timeBetweenChecks: timeBetweenChecks)
now = Date.timeIntervalSinceReferenceDate
} while (now - start) < timeout
}
Expand Down Expand Up @@ -136,8 +149,14 @@ public class STKSolo: NSObject {
let cleanedText = accessibilityCleaned(text: tappableText)
let element = waitForAccessibilityElement { $0.accessibilityLabel == cleanedText }
if let element = element {
if let view = try? UIAccessibilityElement.viewContaining(element, tappable: true) {
var view: UIView? = nil
waitClosureToReturnTrue({ () -> Bool in
view = try? UIAccessibilityElement.viewContaining(element, tappable: true)
return view != nil
}, withinTimeout: timeoutForWaitForMethods, timeBetweenChecks: timeBetweenChecks)
if let view = view {
testActor.tap(element, in: view)
waitRunLoops(timeBetweenChecks: timeBetweenChecks)
} else {
return false
}
Expand Down Expand Up @@ -216,45 +235,42 @@ public class STKSolo: NSObject {
#endif
}

extension STKSolo {

func isUserJenkinsOrHudson() -> Bool {
var username = NSUserName()
#if targetEnvironment(simulator)
if username.isEmpty {
let bundlePathComponents = (Bundle.main.bundlePath as NSString).pathComponents
if bundlePathComponents.count >= 3 && bundlePathComponents[0] == "/" && bundlePathComponents[1] == "Users" {
username = bundlePathComponents[2]
}
}
#endif
return username == "hudson" || username == "jenkins"
}

func isSingleTestRun() -> Bool {
/*
XCTestConfiguration *testConfiguration = [XCTestConfiguration activeTestConfiguration];
// KO when running test of only one class (testsToRun is an Array<String> with class/test names, or just class name)
return [testConfiguration.testsToRun count] == 1 && [[testConfiguration.testsToRun anyObject] containsString:@"/"];
*/
if let plistPath = ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"],
let plistBinary = FileManager.default.contents(atPath: plistPath),
let unarchivedObject = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(plistBinary),
let object = unarchivedObject as? NSObject,
let testsToRun = object.value(forKey: "testsToRun") as? NSSet,
testsToRun.count == 1,
let singleTestToRun = testsToRun.anyObject() as? NSString {
return singleTestToRun.contains("/")
} else {
return false
func isUserJenkinsOrHudson() -> Bool {
var username = NSUserName()
#if targetEnvironment(simulator)
if username.isEmpty {
let bundlePathComponents = (Bundle.main.bundlePath as NSString).pathComponents
if bundlePathComponents.count >= 3 && bundlePathComponents[0] == "/" && bundlePathComponents[1] == "Users" {
username = bundlePathComponents[2]
}
}

func isMultipleTestsRun() -> Bool {
return XCTestSuite.default.testCaseCount > 1
#endif
return username == "hudson" || username == "jenkins"
}

func isSingleTestRun() -> Bool {
/*
XCTestConfiguration *testConfiguration = [XCTestConfiguration activeTestConfiguration];
// KO when running test of only one class (testsToRun is an Array<String> with class/test names, or just class name)
return [testConfiguration.testsToRun count] == 1 && [[testConfiguration.testsToRun anyObject] containsString:@"/"];
*/
if let plistPath = ProcessInfo.processInfo.environment["XCTestConfigurationFilePath"],
let plistBinary = FileManager.default.contents(atPath: plistPath),
let unarchivedObject = try? NSKeyedUnarchiver.unarchiveTopLevelObjectWithData(plistBinary),
let object = unarchivedObject as? NSObject,
let testsToRun = object.value(forKey: "testsToRun") as? NSSet,
testsToRun.count == 1,
let singleTestToRun = testsToRun.anyObject() as? NSString {
return singleTestToRun.contains("/")
} else {
return false
}
}

func isMultipleTestsRun() -> Bool {
return XCTestSuite.default.testCaseCount > 1
}

extension STKSolo: KIFTestActorDelegate {
public func fail(with exception: NSException!, stopTest stop: Bool) {
lastExceptions.append(exception)
Expand Down

0 comments on commit fa2ffbd

Please sign in to comment.