Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adds useCurrentFrame and fix tappable check reliability #1

Merged
merged 16 commits into from
Aug 21, 2024
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
21 changes: 21 additions & 0 deletions KIF Tests/AccessibilityIdentifierTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,27 @@ - (void)testTryFindingViewWithAccessibilityIdentifier
}
}

- (void)testTryFindingOutOfFrameViewWithAccessibilityIdentifier
{
if (![tester tryFindingViewWithAccessibilityIdentifier:@"outOfFrameView"])
{
[tester fail];
}
}

- (void)testTryFindingViewInFrameWithAccessibilityIdentifier
{
if (![tester tryFindingViewInFrameWithAccessibilityIdentifier:@"idGreeting"])
{
[tester fail];
}

if ([tester tryFindingViewInFrameWithAccessibilityIdentifier:@"outOfFrameView"])
{
[tester fail];
}
}

- (void) testTappingStepperIncrement
{
UILabel *uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"];
Expand Down
43 changes: 43 additions & 0 deletions KIF Tests/AccessibilityIdentifierTests_ViewTestActor.m
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,49 @@ - (void)testClearingAndEnteringTextIntoViewWithAccessibilityLabel
[[viewTester usingIdentifier:@"idGreeting"] clearAndEnterText:@"Yo"];
}

- (void)testTryFindingOutOfFrameViewWithAccessibilityIdentifier
{
if (![[viewTester usingIdentifier:@"outOfFrameView"] tryFindingView])
{
[tester fail];
}
}

- (void)testTryFindingViewInFrameWithAccessibilityIdentifier
{
if (![[[viewTester usingCurrentFrame] usingIdentifier:@"idGreeting"] tryFindingView])
{
[tester fail];
}

if ([[[viewTester usingCurrentFrame] usingIdentifier:@"outOfFrameView"] tryFindingView])
{
[tester fail];
}
}

- (void)testTryFindingTappableViewInFrameWithAccessibilityIdentifier
{
if (![[[viewTester usingCurrentFrame] usingIdentifier:@"idGreeting"] tryFindingTappableView])
{
[tester fail];
}

if ([[[viewTester usingCurrentFrame] usingIdentifier:@"outOfFrameView"] tryFindingTappableView])
{
[tester fail];
}
}

- (void)testTryFindingOccludedTappableViewInFrameWithAccessibilityIdentifier
{

if ([[[viewTester usingCurrentFrame] usingIdentifier:@"occludedView"] tryFindingTappableView])
{
[tester fail];
}
}

- (void)afterEach
{
[[[viewTester usingLabel:@"Test Suite"] usingTraits:UIAccessibilityTraitButton] tap];
Expand Down
39 changes: 39 additions & 0 deletions KIF Tests/CustomActionTests_ViewTestActor.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// CustomActionTests_ViewTestActor.m
// KIF Tests
//
// Created by Alex Odawa on 09/07/2024.
//

#import <KIF/KIF.h>

@interface CustomActionTests_ViewTestActor : KIFTestCase
@end


@implementation CustomActionTests_ViewTestActor

- (void)beforeEach
{
[[viewTester usingLabel:@"Tapping"] tap];
}

- (void)afterEach
{
[[[viewTester usingLabel:@"Test Suite"] usingTraits:UIAccessibilityTraitButton] tap];
}

- (void)testCustomActions
{
if (@available(iOS 13.0, *)) {
[[viewTester usingLabel:@"theStepper"] activateCustomActionWithName:@"Action With block handler"];
}

for (NSString *name in @[@"Action without argument", @"Action with argument"]) {
[[viewTester usingLabel:@"theStepper"] activateCustomActionWithName:name];
}

[[viewTester usingLabel:@"theStepper"] activateCustomActionWithName:@"Action that fails" expectedResult:NO];
}

@end
16 changes: 16 additions & 0 deletions KIF.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,11 @@
9CC881AC1AD4CE4B002CD34C /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAB0726B139719AC008AF393 /* Foundation.framework */; };
9CC881AD1AD4CE50002CD34C /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 9CC881A21AD4CAAC002CD34C /* CoreFoundation.framework */; };
9CC967401AD4B1B600576D13 /* KIF.h in Headers */ = {isa = PBXBuildFile; fileRef = 9CC9673F1AD4B1B600576D13 /* KIF.h */; settings = {ATTRIBUTES = (Public, ); }; };
ACA242E42C3DA55400E6F1B6 /* CustomActionTests_ViewTestActor.m in Sources */ = {isa = PBXBuildFile; fileRef = ACA242E32C3DA55400E6F1B6 /* CustomActionTests_ViewTestActor.m */; };
ACA242E72C3DB47400E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = ACA242E52C3DB46A00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m */; };
ACA242E92C3DB4EA00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = ACA242E82C3DB4B000E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h */; settings = {ATTRIBUTES = (Private, ); }; };
ACA242EA2C3DB4EB00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h in Headers */ = {isa = PBXBuildFile; fileRef = ACA242E82C3DB4B000E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h */; settings = {ATTRIBUTES = (Private, ); }; };
ACA242EB2C3DC32500E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = ACA242E52C3DB46A00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m */; };
AE62FCD01A1D20E5002B10DA /* WebViewTests.m in Sources */ = {isa = PBXBuildFile; fileRef = AE62FCCF1A1D20E5002B10DA /* WebViewTests.m */; };
AE62FCD61A1D2447002B10DA /* WebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = AE62FCD51A1D2447002B10DA /* WebViewController.m */; };
AE62FCD81A1D2667002B10DA /* index.html in Resources */ = {isa = PBXBuildFile; fileRef = AE62FCD71A1D2667002B10DA /* index.html */; };
Expand Down Expand Up @@ -427,6 +432,9 @@
9CC9673F1AD4B1B600576D13 /* KIF.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = KIF.h; sourceTree = "<group>"; };
AAB0726B139719AC008AF393 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
AAB072B413971AEA008AF393 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
ACA242E32C3DA55400E6F1B6 /* CustomActionTests_ViewTestActor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CustomActionTests_ViewTestActor.m; sourceTree = "<group>"; };
ACA242E52C3DB46A00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIAccessibilityCustomAction+KIFAdditions.m"; sourceTree = "<group>"; };
ACA242E82C3DB4B000E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIAccessibilityCustomAction+KIFAdditions.h"; sourceTree = "<group>"; };
AE62FCCF1A1D20E5002B10DA /* WebViewTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewTests.m; sourceTree = "<group>"; };
AE62FCD51A1D2447002B10DA /* WebViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WebViewController.m; sourceTree = "<group>"; };
AE62FCD71A1D2667002B10DA /* index.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = index.html; sourceTree = "<group>"; };
Expand Down Expand Up @@ -639,6 +647,8 @@
2229D56F25BEF47D0093296C /* NSPredicate+KIFAdditions.m */,
2229D56125BEF47D0093296C /* NSString+KIFAdditions.h */,
2229D54B25BEF47D0093296C /* NSString+KIFAdditions.m */,
ACA242E82C3DB4B000E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h */,
ACA242E52C3DB46A00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m */,
2229D56425BEF47D0093296C /* UIAccessibilityElement-KIFAdditions.h */,
2229D54825BEF47D0093296C /* UIAccessibilityElement-KIFAdditions.m */,
2229D54C25BEF47D0093296C /* UIApplication-KIFAdditions.h */,
Expand Down Expand Up @@ -922,6 +932,7 @@
FA8A3C5A1A77281900206350 /* WebViewTests_ViewTestActor.m */,
FA8A3C601A77320000206350 /* SystemAlertTests_ViewTestActor.m */,
8E654FC329D79BD8007F7811 /* OffscreenTests_ViewTestActor.m */,
ACA242E32C3DA55400E6F1B6 /* CustomActionTests_ViewTestActor.m */,
);
name = "KIFUIViewTestActor Tests";
sourceTree = "<group>";
Expand Down Expand Up @@ -1000,6 +1011,7 @@
8EC2CB2029DB3D3B001BE493 /* NSObject+KIFSwizzle.h in Headers */,
22B1376F25D6E32700D88061 /* KIFTestActor_Private.h in Headers */,
22B1375025D6E32700D88061 /* KIFTouchVisualizerView.h in Headers */,
ACA242EA2C3DB4EB00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h in Headers */,
22B1377925D6E32700D88061 /* KIFSystemTestActor.h in Headers */,
22B1376D25D6E32700D88061 /* KIFUITestActor-ConditionalTests.h in Headers */,
22B1374F25D6E32700D88061 /* NSString+KIFAdditions.h in Headers */,
Expand Down Expand Up @@ -1037,6 +1049,7 @@
2229D5AB25BEF47D0093296C /* NSError-KIFAdditions.h in Headers */,
2229D5B825BEF47D0093296C /* UIScreen+KIFAdditions.h in Headers */,
2229D5AA25BEF47D0093296C /* UIView-KIFAdditions.h in Headers */,
ACA242E92C3DB4EA00E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.h in Headers */,
2229D5CD25BEF47D0093296C /* KIFTestStepValidation.h in Headers */,
2229D5C225BEF47D0093296C /* LoadableCategory.h in Headers */,
2229D5D625BEF47D0093296C /* KIFTestCase.h in Headers */,
Expand Down Expand Up @@ -1325,6 +1338,7 @@
22B1373A25D6E32700D88061 /* KIFUIObject.m in Sources */,
22B1377425D6E32700D88061 /* KIFTestActor.m in Sources */,
22B1374C25D6E32700D88061 /* UIApplication-KIFAdditions.m in Sources */,
ACA242EB2C3DC32500E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m in Sources */,
8EC2CB2229DB3D3B001BE493 /* NSObject+KIFSwizzle.m in Sources */,
22B1375C25D6E32700D88061 /* KIFUITestActor-ConditionalTests.m in Sources */,
22B1376525D6E32700D88061 /* KIFTypist.m in Sources */,
Expand Down Expand Up @@ -1372,6 +1386,7 @@
2229D5D925BEF47D0093296C /* KIFTestStepValidation.m in Sources */,
2229D5A525BEF47D0093296C /* UIView-Debugging.m in Sources */,
2229D5C125BEF47D0093296C /* NSError-KIFAdditions.m in Sources */,
ACA242E72C3DB47400E6F1B6 /* UIAccessibilityCustomAction+KIFAdditions.m in Sources */,
8EC2CB2129DB3D3B001BE493 /* NSObject+KIFSwizzle.m in Sources */,
2229D5B525BEF47D0093296C /* UIApplication-KIFAdditions.m in Sources */,
2229D5C025BEF47D0093296C /* UIEvent+KIFAdditions.m in Sources */,
Expand Down Expand Up @@ -1423,6 +1438,7 @@
5A62B0AE1BB205CA00A3F480 /* PullToRefreshTests.m in Sources */,
97E8A5D11B0A63D100124E3B /* BackgroundTests.m in Sources */,
EABD46BD1857A0F300A5F081 /* LandscapeTests.m in Sources */,
ACA242E42C3DA55400E6F1B6 /* CustomActionTests_ViewTestActor.m in Sources */,
EABD46BE1857A0F300A5F081 /* TableViewTests.m in Sources */,
FA4915601A7823E500A78E57 /* ScrollViewTests_ViewTestActor.m in Sources */,
EABD46BF1857A0F300A5F081 /* GestureTests.m in Sources */,
Expand Down
21 changes: 21 additions & 0 deletions Sources/KIF/Additions/UIAccessibilityCustomAction+KIFAdditions.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
//
// UIAccessibilityCustomAction+KIFAdditions.h
// KIF
//
// Created by Alex Odawa on 09/07/2024.
//

#import <UIKit/UIKit.h>

@interface NSObject (KIFCustomActionAdditions)

- (UIAccessibilityCustomAction *)KIF_customActionWithName:(NSString *)name;

@end

@interface UIAccessibilityCustomAction (KIFAdditions)

- (BOOL)KIF_activate;

@end

85 changes: 85 additions & 0 deletions Sources/KIF/Additions/UIAccessibilityCustomAction+KIFAdditions.m
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
//
// UIAccessibilityCustomAction+KIFAdditions.m
// KIF Tests
//
// Created by Alex Odawa on 09/07/2024.
//

#import <UIKit/UIKit.h>
#import "UIAccessibilityCustomAction+KIFAdditions.h"



@interface UIAccessibilityCustomAction (KIFPrivate)

- (NSString *)KIF_normalizedName;

@end

@implementation UIAccessibilityCustomAction (KIFAdditions)

- (BOOL)KIF_activate;
{
if (@available(iOS 13.0, *)) {
if (self.actionHandler) {
return self.actionHandler(self);
}
}

if ([self.target respondsToSelector:self.selector]) {
NSMethodSignature *signature = [self.target methodSignatureForSelector:self.selector];
NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
invocation.selector = self.selector;
invocation.target = self.target;

/*
https://developer.apple.com/documentation/uikit/uiaccessibilitycustomaction/1620499-init
The method signature must take one of the following forms:
- (BOOL)myPerformActionMethod
- (BOOL)myPerformActionMethod:(UIAccessibilityCustomAction *)action
*/
if (signature.numberOfArguments == 3) {
id arg = self;
[invocation setArgument: &arg atIndex:2];
}

[invocation invoke];
BOOL returnValue = NO;
[invocation getReturnValue:&returnValue];
return returnValue;
}
NSString *targetStr = [self.target description];
NSString *selectorStr = NSStringFromSelector(self.selector);
[[NSException exceptionWithName:@"KIFUIAccessibilityCustomActionActivationException"
reason:@"UIAccessibilityCustomAction Target does not respond to provided Selector."
userInfo:@{@"Target" : targetStr, @"Selector" : selectorStr}]
raise];

return NO;
}

- (NSString *)KIF_normalizedName;
{
NSString *name = [self name];
if ([name isKindOfClass:[NSAttributedString class]]) {
name = [(NSAttributedString *)name string];
}
return name;
}

@end


@implementation NSObject (KIFCustomActionAdditions)

- (UIAccessibilityCustomAction *)KIF_customActionWithName:(NSString *)name;
{
for (UIAccessibilityCustomAction *action in [self.accessibilityCustomActions copy]) {
if ([name isEqualToString: [action KIF_normalizedName]]) {
return action;
}
}
return nil;
}

@end
23 changes: 23 additions & 0 deletions Sources/KIF/Additions/UIAccessibilityElement-KIFAdditions.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,17 @@
*/
+ (BOOL)accessibilityElement:(out UIAccessibilityElement **)foundElement view:(out UIView **)foundView withElementMatchingPredicate:(NSPredicate *)predicate tappable:(BOOL)mustBeTappable error:(out NSError **)error;

/*!
@abstract Finds an accessibility element and view where the element passes the predicate, optionally passing a tappability test.
@param foundElement The found accessibility element or @c nil if the method returns @c NO. Can be @c NULL.
@param foundView The first matching view for @c foundElement as determined by the accessibility API or @c nil if the view is hidden or fails the tappability test. Can be @c NULL.
@param predicate The predicate to test the accessibility element on.
@param error A reference to an error object to be populated when no matching element or view is found. Can be @c NULL.
@param scrollDisabled Disable scroll performing the search only in the current visible frame.
@result @c YES if the element and view were found. Otherwise @c NO.
*/
+ (BOOL)accessibilityElement:(out UIAccessibilityElement **)foundElement view:(out UIView **)foundView withElementMatchingPredicate:(NSPredicate *)predicate tappable:(BOOL)mustBeTappable error:(out NSError **)error disableScroll:(BOOL)scrollDisabled;

/*!
@abstract Finds and attempts to make visible a view for a given accessibility element.
@discussion If the element is found, off screen, and is inside a scroll view, this method will attempt to programmatically scroll the view onto the screen before performing any logic as to if the view is tappable.
Expand All @@ -103,6 +114,18 @@
*/
+ (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element tappable:(BOOL)mustBeTappable error:(NSError **)error;

/*!
@abstract Finds and attempts to make visible a view for a given accessibility element.
@discussion If the element is found, off screen, and is inside a scroll view, this method will attempt to programmatically scroll the view onto the screen before performing any logic as to if the view is tappable.

@param element The accessibility element.
@param mustBeTappable If @c YES, a tappability test will be performed.
@param error A reference to an error object to be populated when no element is found. Can be @c NULL.
@param scrollDisabled Disable scroll performing the search only in the current visible frame.
@return The first matching view as determined by the accessibility API or nil if the view is hidden or fails the tappability test.
*/
+ (UIView *)viewContainingAccessibilityElement:(UIAccessibilityElement *)element tappable:(BOOL)mustBeTappable error:(NSError **)error disableScroll:(BOOL)scrollDisabled;

/*!
@abstract Returns a human readable string of UIAccessiblityTrait names, derived from UIAccessibilityConstants.h.
@param traits The accessibility traits to list.
Expand Down
Loading