Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
// swift-tools-version:5.3
// swift-tools-version:5.9
// The swift-tools-version declares the minimum version of Swift required to build this package.
import PackageDescription

let package = Package(
name: "KIF",
platforms: [
.iOS(.v13)
.iOS(.v15)
],
products: [
.library(
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ KIF builds and performs the tests using a standard `XCTest` testing target. Tes

**KIF uses undocumented Apple APIs.** This is true of most iOS testing frameworks, and is safe for testing purposes, but it's important that KIF does not make it into production code, as it will get your app submission denied by Apple. Follow the instructions below to ensure that KIF is configured correctly for your project.

**Actively supports Xcode 11.6 and iOS 11-13 if you need support for an earlier version please use [v3.7.9](https://github.com/kif-framework/KIF/releases/tag/v3.7.9) or an [earlier release](https://github.com/kif-framework/KIF/releases).**
**Actively supports Xcode 16 and iOS 15 if you need support for an earlier version please use an [earlier release](https://github.com/kif-framework/KIF/releases).**

Features
--------
Expand Down
3 changes: 0 additions & 3 deletions Scripts/ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,6 @@ if [ $RUN_EXTRA_VALIDATIONS != "true" ]; then
exit 0
fi

# Compile the KIF SPM package directly
swift build -Xcc "-isysroot" -Xcc "$(xcrun --sdk iphonesimulator --show-sdk-path)" -Xcc "-target" -Xcc "x86_64-apple-ios$(xcrun --sdk iphonesimulator --show-sdk-version)-simulator"

# Consume KIF via Swift Package Manager in an Xcode project
env NSUnbufferedIO=YES xcodebuild test -project "Documentation/Examples/SPMIntegration/SPMIntegration.xcodeproj" -scheme "SPMIntegration" -derivedDataPath=${PWD}/build/SPMIntegration -destination "platform=iOS Simulator,${SIMULATOR}" CODE_SIGNING_ALLOWED=NO | xcbeautify

Expand Down
11 changes: 1 addition & 10 deletions Sources/KIF/Additions/UIAccessibilityElement-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -218,16 +218,7 @@ + (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element
CGRect elementFrame = [view.window convertRect:element.accessibilityFrame toView:scrollView];
CGRect visibleRect = CGRectMake(scrollView.contentOffset.x, scrollView.contentOffset.y, CGRectGetWidth(scrollView.bounds), CGRectGetHeight(scrollView.bounds));

UIEdgeInsets contentInset;
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {
contentInset = scrollView.adjustedContentInset;
} else {
contentInset = scrollView.contentInset;
}
#else
contentInset = scrollView.contentInset;
#endif
UIEdgeInsets contentInset = scrollView.adjustedContentInset;
visibleRect = UIEdgeInsetsInsetRect(visibleRect, contentInset);

// Only call scrollRectToVisible if the element isn't already visible
Expand Down
6 changes: 1 addition & 5 deletions Sources/KIF/Additions/UIApplication-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,6 @@ - (BOOL)KIF_openURL:(NSURL *)URL;
}
}

#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
- (BOOL)KIF_openURL:(NSURL *)URL options:(NSDictionary<NSString *, id> *)options completionHandler:(void (^ __nullable)(BOOL success))completionHandler;
{
if (_KIF_UIApplicationMockOpenURL) {
Expand All @@ -328,7 +327,6 @@ - (BOOL)KIF_openURL:(NSURL *)URL options:(NSDictionary<NSString *, id> *)options
return [self KIF_openURL:URL options: options completionHandler: completionHandler];
}
}
#endif

- (BOOL)KIF_canOpenURL:(NSURL *)URL;
{
Expand Down Expand Up @@ -368,9 +366,7 @@ + (void)startMockingOpenURLWithReturnValue:(BOOL)returnValue;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
Swizzle(self, @selector(openURL:), @selector(KIF_openURL:));
#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000
Swizzle(self, @selector(openURL:options:completionHandler:), @selector(KIF_openURL:options:completionHandler:));
#endif
Swizzle(self, @selector(openURL:options:completionHandler:), @selector(KIF_openURL:options:completionHandler:));
Swizzle(self, @selector(canOpenURL:), @selector(KIF_canOpenURL:));
});

Expand Down
11 changes: 1 addition & 10 deletions Sources/KIF/Additions/UIScrollView-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,7 @@ - (void)scrollViewToVisible:(UIView *)view animated:(BOOL)animated;
contentOffset.y = MAX(CGRectGetMaxY(viewFrame) - CGRectGetHeight(self.bounds), CGRectGetMinY(viewFrame));
}

UIEdgeInsets contentInset;
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {
contentInset = self.adjustedContentInset;
} else {
contentInset = self.contentInset;
}
#else
contentInset = self.contentInset;
#endif
UIEdgeInsets contentInset = self.adjustedContentInset;
CGFloat minX = -self.contentInset.left;
CGFloat maxX = minX + MAX(0, self.contentSize.width + contentInset.left + contentInset.right - CGRectGetWidth(self.bounds));
CGFloat minY = -self.contentInset.top;
Expand Down
4 changes: 0 additions & 4 deletions Sources/KIF/Additions/UIView-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -579,10 +579,6 @@ - (void)tapAtPoint:(CGPoint)point;
id /*UIWebBrowserView*/ webBrowserView = nil;

BOOL isWebView = [self isKindOfClass:[WKWebView class]];

#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_12_0
isWebView = isWebView || [self isKindOfClass:[UIWebView class]];
#endif

if ([NSStringFromClass([self class]) isEqual:@"UIWebBrowserView"]) {
webBrowserView = self;
Expand Down
11 changes: 0 additions & 11 deletions Sources/KIF/Additions/XCTestCase-KIFAdditions.m
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,6 @@ - (void)failWithException:(NSException *)exception stopTest:(BOOL)stop
{
self.continueAfterFailure = YES;

#ifdef __IPHONE_14_0
NSString *filePath = exception.userInfo[@"FilenameKey"];
NSInteger lineNumber = [exception.userInfo[@"LineNumberKey"] unsignedIntegerValue];
XCTSourceCodeLocation *location = [[XCTSourceCodeLocation alloc] initWithFilePath:filePath
Expand All @@ -47,9 +46,6 @@ - (void)failWithException:(NSException *)exception stopTest:(BOOL)stop
associatedError:nil
attachments:@[]];
[self recordIssue:issue];
#else
[self recordFailureWithDescription:exception.description inFile:exception.userInfo[@"FilenameKey"] atLine:[exception.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO];
#endif

if (stop) {
[self writeScreenshotForException:exception];
Expand Down Expand Up @@ -155,7 +151,6 @@ - (void)printViewHierarchyIfOptedIn;

@end

#ifdef __IPHONE_8_0

@interface XCTestSuite ()
- (void)_recordUnexpectedFailureForTestRun:(id)arg1 description:(id)arg2 exception:(id)arg3;
Expand All @@ -173,7 +168,6 @@ - (void)KIF_recordUnexpectedFailureForTestRun:(XCTestSuiteRun *)arg1 description
if (![[arg3 name] isEqualToString:@"KIFFailureException"]) {
[self KIF_recordUnexpectedFailureForTestRun:arg1 description:arg2 exception:arg3];
} else {
#ifdef __IPHONE_14_0
NSString *description = [NSString stringWithFormat:@"Test suite stopped on fatal error: %@", arg3.description];
NSString *filePath = arg3.userInfo[@"FilenameKey"];
NSInteger lineNumber = [arg3.userInfo[@"LineNumberKey"] unsignedIntegerValue];
Expand All @@ -187,12 +181,7 @@ - (void)KIF_recordUnexpectedFailureForTestRun:(XCTestSuiteRun *)arg1 description
associatedError:nil
attachments:@[]];
[arg1 recordIssue:issue];
#else
[arg1 recordFailureWithDescription:[NSString stringWithFormat:@"Test suite stopped on fatal error: %@", arg3.description] inFile:arg3.userInfo[@"FilenameKey"] atLine:[arg3.userInfo[@"LineNumberKey"] unsignedIntegerValue] expected:NO];
#endif
}
}

@end

#endif
4 changes: 0 additions & 4 deletions Sources/KIF/Classes/KIFSystemTestActor.m
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,6 @@ - (void)simulateMemoryWarning

- (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation
{
#ifdef __IPHONE_16_0
if (@available(iOS 16.0, *)) {
NSSet<UIScene *> *scenes = [[UIApplication sharedApplication] connectedScenes];
UIWindowScene* windowScene;
Expand Down Expand Up @@ -101,11 +100,8 @@ - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation
}];
}
} else {
#endif
[[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"];
#ifdef __IPHONE_16_0
}
#endif
}


Expand Down
104 changes: 47 additions & 57 deletions Sources/KIF/Classes/KIFTextInputTraitsOverrides.m
Original file line number Diff line number Diff line change
Expand Up @@ -108,68 +108,58 @@ + (void)KIFSwizzleTextInputFieldsAutocorrect

+ (void)KIFSwizzleTextInputFieldsSmartDashes
{
// This #ifdef is necessary for versions of Xcode before Xcode 9.
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct objc_method_description smartDashesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartDashesType), NO, YES);
send_type_uitextfield smartDashesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)];
send_type_uitextview smartDashesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)];

IMP smartDashesImp_textField = imp_implementationWithBlock(^(UITextField *_self) {
if(self.allowDefaultSmartDashesBehavior) {
return smartDashesOriginalImp_textField(_self, @selector(smartQuotesType));
} else {
return UITextSmartDashesTypeNo;
}
});
IMP smartDashesImp_textView = imp_implementationWithBlock(^(UITextView *_self) {
if(self.allowDefaultSmartDashesBehavior) {
return smartDashesOriginalImp_textView(_self, @selector(smartQuotesType));
} else {
return UITextSmartDashesTypeNo;
}
});

class_replaceMethod([UITextField class], @selector(smartDashesType), smartDashesImp_textField, smartDashesTypeMethodDescription.types);
class_replaceMethod([UITextView class], @selector(smartDashesType), smartDashesImp_textView, smartDashesTypeMethodDescription.types);
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct objc_method_description smartDashesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartDashesType), NO, YES);
send_type_uitextfield smartDashesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)];
send_type_uitextview smartDashesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)];

IMP smartDashesImp_textField = imp_implementationWithBlock(^(UITextField *_self) {
if(self.allowDefaultSmartDashesBehavior) {
return smartDashesOriginalImp_textField(_self, @selector(smartQuotesType));
} else {
return UITextSmartDashesTypeNo;
}
});
}
#endif
IMP smartDashesImp_textView = imp_implementationWithBlock(^(UITextView *_self) {
if(self.allowDefaultSmartDashesBehavior) {
return smartDashesOriginalImp_textView(_self, @selector(smartQuotesType));
} else {
return UITextSmartDashesTypeNo;
}
});

class_replaceMethod([UITextField class], @selector(smartDashesType), smartDashesImp_textField, smartDashesTypeMethodDescription.types);
class_replaceMethod([UITextView class], @selector(smartDashesType), smartDashesImp_textView, smartDashesTypeMethodDescription.types);
});
}

+ (void)KIFSwizzleTextInputFieldsSmartQuotes
{
// This #ifdef is necessary for versions of Xcode before Xcode 9.
#ifdef __IPHONE_11_0
if (@available(iOS 11.0, *)) {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct objc_method_description smartQuotesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartQuotesType), NO, YES);
send_type_uitextfield smartQuotesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)];
send_type_uitextview smartQuotesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)];

IMP smartQuotesImp_textField = imp_implementationWithBlock(^(UITextField *_self) {
if(self.allowDefaultSmartQuotesBehavior) {
return smartQuotesOriginalImp_textField(_self, @selector(smartQuotesType));
} else {
return UITextSmartQuotesTypeNo;
}
});
IMP smartQuotesImp_textView = imp_implementationWithBlock(^(UITextView *_self) {
if(self.allowDefaultSmartQuotesBehavior) {
return smartQuotesOriginalImp_textView(_self, @selector(smartQuotesType));
} else {
return UITextSmartQuotesTypeNo;
}
});

class_replaceMethod([UITextField class], @selector(smartQuotesType), smartQuotesImp_textField, smartQuotesTypeMethodDescription.types);
class_replaceMethod([UITextView class], @selector(smartQuotesType), smartQuotesImp_textView, smartQuotesTypeMethodDescription.types);
});
}
#endif
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
struct objc_method_description smartQuotesTypeMethodDescription = protocol_getMethodDescription(@protocol(UITextInputTraits), @selector(smartQuotesType), NO, YES);
send_type_uitextfield smartQuotesOriginalImp_textField = (send_type_uitextfield)[UITextField instanceMethodForSelector:@selector(smartDashesType)];
send_type_uitextview smartQuotesOriginalImp_textView = (send_type_uitextview)[UITextView instanceMethodForSelector:@selector(smartDashesType)];

IMP smartQuotesImp_textField = imp_implementationWithBlock(^(UITextField *_self) {
if(self.allowDefaultSmartQuotesBehavior) {
return smartQuotesOriginalImp_textField(_self, @selector(smartQuotesType));
} else {
return UITextSmartQuotesTypeNo;
}
});
IMP smartQuotesImp_textView = imp_implementationWithBlock(^(UITextView *_self) {
if(self.allowDefaultSmartQuotesBehavior) {
return smartQuotesOriginalImp_textView(_self, @selector(smartQuotesType));
} else {
return UITextSmartQuotesTypeNo;
}
});

class_replaceMethod([UITextField class], @selector(smartQuotesType), smartQuotesImp_textField, smartQuotesTypeMethodDescription.types);
class_replaceMethod([UITextView class], @selector(smartQuotesType), smartQuotesImp_textView, smartQuotesTypeMethodDescription.types);
});
}

@end
2 changes: 0 additions & 2 deletions Sources/KIF/Classes/UIAutomationHelper.m
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ - (UIAAlert *)currentSystemAlert
UIAApplication *application = [[self target] frontMostApp];
UIAAlert *alert = application.alert;

#ifdef __IPHONE_13_1
if ([alert isKindOfClass:[self nilElementClass]]) {
// application.alert returns UIAElementNil on iOS 13.1
// Instead find the alert by looking for the alert's window and getting the UIAAlert off of it
Expand All @@ -132,7 +131,6 @@ - (UIAAlert *)currentSystemAlert
return [[evaluatedObject valueForKey:@"type"] isEqualToString:@"_UIAlertControllerView"];
}]] firstObject];
}
#endif

return alert;
}
Expand Down
Loading