From 4458d3a910c4944bdd31c3f5de78fdd28af82953 Mon Sep 17 00:00:00 2001 From: meidlinga <1284704+meidlinga@users.noreply.github.com> Date: Tue, 19 Jul 2022 13:45:44 +0200 Subject: [PATCH 01/74] Fix quotes in README Use inline code formatting to prevent interpretation of special characters as formatting syntax --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 346b18a9b..197ff00c2 100644 --- a/README.md +++ b/README.md @@ -128,7 +128,7 @@ You need your tests to run hosted in your application. **Xcode does this for you First add your application by selecting "Build Phases", expanding the "Target Dependencies" section, clicking on the "+" button, and in the new sheet that appears selecting your application target and clicking "Add". -Next, configure your bundle loader. In "Build Settings", expand "Linking" and edit "Bundle Loader" to be "$(TEST_HOST)". Expand the "Testing" section and edit "Test Host" to be "$(BUILT_PRODUCTS_DIR)/MyApplication.app/MyApplication" where "MyApplication" is the name of your app. Also make sure that "Wrapper Extension" is set to "xctest". +Next, configure your bundle loader. In "Build Settings", expand "Linking" and edit "Bundle Loader" to be `$(TEST_HOST)`. Expand the "Testing" section and edit "Test Host" to be `$(BUILT_PRODUCTS_DIR)/MyApplication.app/MyApplication` where `MyApplication` is the name of your app. Also make sure that "Wrapper Extension" is set to `xctest`. The last step is to configure your unit tests to run when you trigger a test (⌘U). Click on your scheme name and select "Edit Scheme…". Click on "Test" in the sidebar followed by the "+" in the bottom left corner. Select your testing target and click "OK". From 11d293331fa7cd1e1f4e455fba2183f7ace8e692 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Sun, 19 Feb 2023 16:07:16 +1100 Subject: [PATCH 02/74] Fix iOS 16 bugs --- Sources/KIF/Additions/UIView-KIFAdditions.m | 37 +++++++++++++++++ Sources/KIF/Classes/KIFSystemTestActor.m | 45 ++++++++++++++++++++- Sources/KIF/Classes/KIFUITestActor.m | 5 +++ 3 files changed, 86 insertions(+), 1 deletion(-) diff --git a/Sources/KIF/Additions/UIView-KIFAdditions.m b/Sources/KIF/Additions/UIView-KIFAdditions.m index a9e9e2976..7e599e21d 100644 --- a/Sources/KIF/Additions/UIView-KIFAdditions.m +++ b/Sources/KIF/Additions/UIView-KIFAdditions.m @@ -164,6 +164,14 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi // UITableViewCell is such an offender. for (UIView *view in [self.subviews reverseObjectEnumerator]) { UIAccessibilityElement *element = [view accessibilityElementMatchingBlock:matchBlock]; + + if (!element) { + if([view isKindOfClass:NSClassFromString(@"_UIRemoteKeyboardPlaceholderView")]) { + UIView* fallbackView = [view valueForKey:@"_fallbackView"]; + element = [fallbackView accessibilityElementMatchingBlock:matchBlock]; + } + } + if (!element) { continue; } @@ -374,12 +382,25 @@ - (NSArray *)subviewsWithClassNamePrefix:(NSString *)prefix; if ([NSStringFromClass([view class]) hasPrefix:prefix]) { [result addObject:view]; } + + if([NSStringFromClass([view class]) isEqualToString:@"_UIRemoteKeyboardPlaceholderView"]) { + UIView* fallbackView = [view valueForKey:@"_fallbackView"]; + if ([NSStringFromClass([fallbackView class]) hasPrefix:prefix]) { + [result addObject:fallbackView]; + } + } } // Now traverse the subviews of the subviews, adding matches. for (UIView *view in self.subviews) { NSArray *matchingSubviews = [view subviewsWithClassNamePrefix:prefix]; [result addObjectsFromArray:matchingSubviews]; + + if([NSStringFromClass([view class]) isEqualToString:@"_UIRemoteKeyboardPlaceholderView"]) { + UIView* fallbackView = [view valueForKey:@"_fallbackView"]; + NSArray *matchingSubviews = [fallbackView subviewsWithClassNamePrefix:prefix]; + [result addObjectsFromArray:matchingSubviews]; + } } return result; @@ -403,14 +424,30 @@ - (NSArray *)subviewsWithClassNameOrSuperClassNamePrefix:(NSString *)prefix; // First traverse the next level of subviews, adding matches for (UIView *view in self.subviews) { Class klass = [view class]; + while (klass) { if ([NSStringFromClass(klass) hasPrefix:prefix]) { [result addObject:view]; break; } + if([NSStringFromClass(klass) isEqualToString:@"_UIRemoteKeyboardPlaceholderView"]) { + UIView* fallbackView = [view valueForKey:@"_fallbackView"]; + Class klass = [fallbackView class]; + while (klass) { + if ([NSStringFromClass(klass) hasPrefix:prefix]) { + [result addObject:fallbackView]; + break; + } + + klass = [klass superclass]; + } + } + klass = [klass superclass]; } + + } // Now traverse the subviews of the subviews, adding matches diff --git a/Sources/KIF/Classes/KIFSystemTestActor.m b/Sources/KIF/Classes/KIFSystemTestActor.m index ef8deebb7..081e5ba66 100644 --- a/Sources/KIF/Classes/KIFSystemTestActor.m +++ b/Sources/KIF/Classes/KIFSystemTestActor.m @@ -58,7 +58,50 @@ - (void)simulateMemoryWarning - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation { - [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"]; + if (@available(iOS 16.0, *)) { + NSSet *scenes = [[UIApplication sharedApplication] connectedScenes]; + UIWindowScene* windowScene; + for (UIScene* scene in scenes) { + if([scene isKindOfClass:[UIWindowScene class]]) { + windowScene = (UIWindowScene*) scene; + break; + } + } + + if (windowScene) { + UIInterfaceOrientationMask orientationMask; + switch (orientation) { + case UIDeviceOrientationUnknown: + orientationMask = UIInterfaceOrientationMaskAll; + break; + case UIDeviceOrientationPortrait: + orientationMask = UIInterfaceOrientationMaskPortrait; + break; + case UIDeviceOrientationPortraitUpsideDown: + orientationMask = UIInterfaceOrientationMaskPortraitUpsideDown; + break; + case UIDeviceOrientationLandscapeLeft: + orientationMask = UIInterfaceOrientationMaskLandscapeLeft; + break; + case UIDeviceOrientationLandscapeRight: + orientationMask = UIInterfaceOrientationMaskLandscapeRight; + break; + case UIDeviceOrientationFaceUp: + orientationMask = UIInterfaceOrientationMaskAll; + break; + case UIDeviceOrientationFaceDown: + orientationMask = UIInterfaceOrientationMaskAll; + break; + } + + UIWindowSceneGeometryPreferencesIOS* preferences = [[UIWindowSceneGeometryPreferencesIOS alloc]initWithInterfaceOrientations:orientationMask]; + [windowScene requestGeometryUpdateWithPreferences:preferences errorHandler:^(NSError * _Nonnull error) { + NSLog(@"error: %@", error); + }]; + } + } else { + [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"]; + } } diff --git a/Sources/KIF/Classes/KIFUITestActor.m b/Sources/KIF/Classes/KIFUITestActor.m index 456af62cb..a79d8ff80 100644 --- a/Sources/KIF/Classes/KIFUITestActor.m +++ b/Sources/KIF/Classes/KIFUITestActor.m @@ -835,11 +835,16 @@ - (void)selectPickerViewRowWithTitle:(NSString *)title inComponent:(NSInteger)co // Find all pickers in view. Either UIDatePickerView or UIPickerView NSArray *datePickerViews = [[[UIApplication sharedApplication] datePickerWindow] subviewsWithClassNameOrSuperClassNamePrefix:@"UIPickerView"]; NSArray *pickerViews = [[[UIApplication sharedApplication] pickerViewWindow] subviewsWithClassNameOrSuperClassNamePrefix:@"UIPickerView"]; + + NSArray *iOS16DatePickerViews = [[[UIApplication sharedApplication] datePickerWindow] subviewsWithClassNameOrSuperClassNamePrefix:@"UIDatePicker"]; // Grab one picker and assume it is datePicker and then test our hypothesis later! pickerView = [datePickerViews lastObject]; if ([pickerView respondsToSelector:@selector(setDate:animated:)] || [pickerView isKindOfClass:NSClassFromString(@"_UIDatePickerView")]) { pickerType = KIFUIDatePicker; + }else if([[iOS16DatePickerViews lastObject] respondsToSelector:@selector(setDate:animated:)]) { + pickerView = [[iOS16DatePickerViews lastObject] valueForKey:@"_pickerView"]; + pickerType = KIFUIDatePicker; } else { pickerView = [pickerViews lastObject]; pickerType = KIFUIPickerView; From b912934244e4d29d59e995ad001a67be736ee6c5 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Wed, 22 Feb 2023 20:42:18 +1100 Subject: [PATCH 03/74] Add error if device fails to rotate --- Sources/KIF/Classes/KIFSystemTestActor.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/KIF/Classes/KIFSystemTestActor.m b/Sources/KIF/Classes/KIFSystemTestActor.m index 081e5ba66..9a8cde899 100644 --- a/Sources/KIF/Classes/KIFSystemTestActor.m +++ b/Sources/KIF/Classes/KIFSystemTestActor.m @@ -96,7 +96,7 @@ - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation UIWindowSceneGeometryPreferencesIOS* preferences = [[UIWindowSceneGeometryPreferencesIOS alloc]initWithInterfaceOrientations:orientationMask]; [windowScene requestGeometryUpdateWithPreferences:preferences errorHandler:^(NSError * _Nonnull error) { - NSLog(@"error: %@", error); + [self failWithError:[NSError KIFErrorWithUnderlyingError:error format:@"Could not rotate the screen"] stopTest:YES]; }]; } } else { From 2c8aaeacbe234efdf2f50f5d051a448926424f13 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Wed, 22 Feb 2023 21:21:34 +1100 Subject: [PATCH 04/74] Refactor iOS16 Keyboard Fallback View logic --- Sources/KIF/Additions/UIView-KIFAdditions.m | 30 ++++++++++++--------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/Sources/KIF/Additions/UIView-KIFAdditions.m b/Sources/KIF/Additions/UIView-KIFAdditions.m index 7e599e21d..8719057d0 100644 --- a/Sources/KIF/Additions/UIView-KIFAdditions.m +++ b/Sources/KIF/Additions/UIView-KIFAdditions.m @@ -166,10 +166,8 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi UIAccessibilityElement *element = [view accessibilityElementMatchingBlock:matchBlock]; if (!element) { - if([view isKindOfClass:NSClassFromString(@"_UIRemoteKeyboardPlaceholderView")]) { - UIView* fallbackView = [view valueForKey:@"_fallbackView"]; - element = [fallbackView accessibilityElementMatchingBlock:matchBlock]; - } + UIView* fallbackView = [self tryGetiOS16KeyboardFallbackViewFromParentView:view]; + element = [fallbackView accessibilityElementMatchingBlock:matchBlock]; } if (!element) { @@ -383,11 +381,9 @@ - (NSArray *)subviewsWithClassNamePrefix:(NSString *)prefix; [result addObject:view]; } - if([NSStringFromClass([view class]) isEqualToString:@"_UIRemoteKeyboardPlaceholderView"]) { - UIView* fallbackView = [view valueForKey:@"_fallbackView"]; - if ([NSStringFromClass([fallbackView class]) hasPrefix:prefix]) { - [result addObject:fallbackView]; - } + UIView* fallbackView = [self tryGetiOS16KeyboardFallbackViewFromParentView:view]; + if ([NSStringFromClass([fallbackView class]) hasPrefix:prefix]) { + [result addObject:fallbackView]; } } @@ -396,8 +392,8 @@ - (NSArray *)subviewsWithClassNamePrefix:(NSString *)prefix; NSArray *matchingSubviews = [view subviewsWithClassNamePrefix:prefix]; [result addObjectsFromArray:matchingSubviews]; - if([NSStringFromClass([view class]) isEqualToString:@"_UIRemoteKeyboardPlaceholderView"]) { - UIView* fallbackView = [view valueForKey:@"_fallbackView"]; + UIView* fallbackView = [self tryGetiOS16KeyboardFallbackViewFromParentView:view]; + if (fallbackView) { NSArray *matchingSubviews = [fallbackView subviewsWithClassNamePrefix:prefix]; [result addObjectsFromArray:matchingSubviews]; } @@ -431,8 +427,8 @@ - (NSArray *)subviewsWithClassNameOrSuperClassNamePrefix:(NSString *)prefix; break; } - if([NSStringFromClass(klass) isEqualToString:@"_UIRemoteKeyboardPlaceholderView"]) { - UIView* fallbackView = [view valueForKey:@"_fallbackView"]; + UIView* fallbackView = [self tryGetiOS16KeyboardFallbackViewFromParentView:view]; + if (fallbackView) { Class klass = [fallbackView class]; while (klass) { if ([NSStringFromClass(klass) hasPrefix:prefix]) { @@ -1057,5 +1053,13 @@ - (void)performBlockOnAscendentViews:(void (^)(UIView *view, BOOL *stop))block } } +-(UIView*)tryGetiOS16KeyboardFallbackViewFromParentView:(UIView*) parentView { + if([parentView isKindOfClass:NSClassFromString(@"_UIRemoteKeyboardPlaceholderView")]) { + UIView* fallbackView = [parentView valueForKey:@"_fallbackView"]; + return fallbackView; + } + + return nil; +} @end From 719c9cdee14d2f1b0394a5b52068b6928ec7dda4 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Wed, 22 Feb 2023 21:35:41 +1100 Subject: [PATCH 05/74] Add iOS 16 CI tests --- .github/workflows/build.yml | 54 +++++++++++-------------------------- 1 file changed, 15 insertions(+), 39 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index eb7da88ea..5f3adefee 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -15,17 +15,13 @@ jobs: - name: Validate podspec run: pod lib lint - build: - runs-on: macos-11 + build_xcode14: + runs-on: macos-12 strategy: matrix: run-config: - - { xcode_version: '11.7', simulator: 'name=iPhone SE (2nd generation),OS=13.7' } - - { xcode_version: '12.5.1', simulator: 'name=iPhone SE (2nd generation),OS=14.5' } - - { xcode_version: '13.0', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=15.0' } - - - steps: + - { xcode_version: '14.1', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=16.1' } + steps: &build_steps - name: Checkout Project uses: actions/checkout@v1 @@ -56,6 +52,16 @@ jobs: - name: Build & Test run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" + build: + runs-on: macos-11 + strategy: + matrix: + run-config: + - { xcode_version: '11.7', simulator: 'name=iPhone SE (2nd generation),OS=13.7' } + - { xcode_version: '12.5.1', simulator: 'name=iPhone SE (2nd generation),OS=14.5' } + - { xcode_version: '13.0', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=15.0' } + steps: *build_steps + build_xcode10: runs-on: macos-10.15 strategy: @@ -63,34 +69,4 @@ jobs: run-config: - { xcode_version: '10.3', simulator: 'name=iPad (5th generation),OS=12.4' } - { xcode_version: '10.3', simulator: 'name=iPhone 8,OS=12.4' } - - steps: - - name: Checkout Project - uses: actions/checkout@v1 - - - name: Brew Update - run: brew update - - - name: Install Bundler - run: gem install bundler - - - name: Install Core Utils - run: if [ -z "$(brew ls --versions coreutils)" ] ; then brew install coreutils ; fi - - - name: Install XCPretty - run: gem install xcpretty --no-document --quiet - - - name: Show Xcode versions - run: ls -al /Applications/Xcode* - - - name: Select Xcode - run: sudo xcode-select -s /Applications/Xcode_${{ matrix.run-config['xcode_version'] }}.app - - - name: Current Xcode Selected - run: xcode-select -p - - - name: List Simulators - run: xcrun simctl list - - - name: Build & Test - run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" + steps: *build_steps From ee054964fb230b1d57f521315a9aa3919a632e2b Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Thu, 23 Feb 2023 22:33:25 +1100 Subject: [PATCH 06/74] Fix github yml --- .github/workflows/build.yml | 64 +++++++++++++++++++++++++++++++++++-- 1 file changed, 61 insertions(+), 3 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5f3adefee..597e343c8 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: matrix: run-config: - { xcode_version: '14.1', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=16.1' } - steps: &build_steps + steps: - name: Checkout Project uses: actions/checkout@v1 @@ -60,7 +60,36 @@ jobs: - { xcode_version: '11.7', simulator: 'name=iPhone SE (2nd generation),OS=13.7' } - { xcode_version: '12.5.1', simulator: 'name=iPhone SE (2nd generation),OS=14.5' } - { xcode_version: '13.0', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=15.0' } - steps: *build_steps + steps: + - name: Checkout Project + uses: actions/checkout@v1 + + - name: Brew Update + run: brew update + + - name: Install Bundler + run: gem install bundler + + - name: Install Core Utils + run: if [ -z "$(brew ls --versions coreutils)" ] ; then brew install coreutils ; fi + + - name: Install XCPretty + run: gem install xcpretty --no-document --quiet + + - name: Show Xcode versions + run: ls -al /Applications/Xcode* + + - name: Select Xcode + run: sudo xcode-select -s /Applications/Xcode_${{ matrix.run-config['xcode_version'] }}.app + + - name: Current Xcode Selected + run: xcode-select -p + + - name: List Simulators + run: xcrun simctl list + + - name: Build & Test + run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" build_xcode10: runs-on: macos-10.15 @@ -69,4 +98,33 @@ jobs: run-config: - { xcode_version: '10.3', simulator: 'name=iPad (5th generation),OS=12.4' } - { xcode_version: '10.3', simulator: 'name=iPhone 8,OS=12.4' } - steps: *build_steps + steps: + - name: Checkout Project + uses: actions/checkout@v1 + + - name: Brew Update + run: brew update + + - name: Install Bundler + run: gem install bundler + + - name: Install Core Utils + run: if [ -z "$(brew ls --versions coreutils)" ] ; then brew install coreutils ; fi + + - name: Install XCPretty + run: gem install xcpretty --no-document --quiet + + - name: Show Xcode versions + run: ls -al /Applications/Xcode* + + - name: Select Xcode + run: sudo xcode-select -s /Applications/Xcode_${{ matrix.run-config['xcode_version'] }}.app + + - name: Current Xcode Selected + run: xcode-select -p + + - name: List Simulators + run: xcrun simctl list + + - name: Build & Test + run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" From 13ccb560ca1045107600f854d168ae753ccb4e16 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Sat, 25 Feb 2023 20:11:29 +1100 Subject: [PATCH 07/74] Add conditional to remove iOS 16 from old Xcodes --- Sources/KIF/Classes/KIFSystemTestActor.m | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Sources/KIF/Classes/KIFSystemTestActor.m b/Sources/KIF/Classes/KIFSystemTestActor.m index 9a8cde899..c1ae0d649 100644 --- a/Sources/KIF/Classes/KIFSystemTestActor.m +++ b/Sources/KIF/Classes/KIFSystemTestActor.m @@ -58,6 +58,7 @@ - (void)simulateMemoryWarning - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation { +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 16000 if (@available(iOS 16.0, *)) { NSSet *scenes = [[UIApplication sharedApplication] connectedScenes]; UIWindowScene* windowScene; @@ -100,8 +101,11 @@ - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation }]; } } else { +#endif [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"]; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 16000 } +#endif } From 708ab8757675d90c3b1a667813ce1e5fe7f7e5be Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Sat, 25 Feb 2023 20:23:48 +1100 Subject: [PATCH 08/74] Update CI to test on iPhone SE and iPad pro, Xcode 13 and 14 --- .github/workflows/build.yml | 44 +++---------------------------------- 1 file changed, 3 insertions(+), 41 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 597e343c8..00051162f 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,6 +21,7 @@ jobs: matrix: run-config: - { xcode_version: '14.1', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=16.1' } + - { xcode_version: '14.1', simulator: 'name=iPhone SE (3nd generation),OS=16.1' } steps: - name: Checkout Project uses: actions/checkout@v1 @@ -57,8 +58,7 @@ jobs: strategy: matrix: run-config: - - { xcode_version: '11.7', simulator: 'name=iPhone SE (2nd generation),OS=13.7' } - - { xcode_version: '12.5.1', simulator: 'name=iPhone SE (2nd generation),OS=14.5' } + - { xcode_version: '13.0', simulator: 'name=iPhone SE (2nd generation),OS=15.0' } - { xcode_version: '13.0', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=15.0' } steps: - name: Checkout Project @@ -89,42 +89,4 @@ jobs: run: xcrun simctl list - name: Build & Test - run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" - - build_xcode10: - runs-on: macos-10.15 - strategy: - matrix: - run-config: - - { xcode_version: '10.3', simulator: 'name=iPad (5th generation),OS=12.4' } - - { xcode_version: '10.3', simulator: 'name=iPhone 8,OS=12.4' } - steps: - - name: Checkout Project - uses: actions/checkout@v1 - - - name: Brew Update - run: brew update - - - name: Install Bundler - run: gem install bundler - - - name: Install Core Utils - run: if [ -z "$(brew ls --versions coreutils)" ] ; then brew install coreutils ; fi - - - name: Install XCPretty - run: gem install xcpretty --no-document --quiet - - - name: Show Xcode versions - run: ls -al /Applications/Xcode* - - - name: Select Xcode - run: sudo xcode-select -s /Applications/Xcode_${{ matrix.run-config['xcode_version'] }}.app - - - name: Current Xcode Selected - run: xcode-select -p - - - name: List Simulators - run: xcrun simctl list - - - name: Build & Test - run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" + run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" \ No newline at end of file From 5f643d68959f749ff7fea0e379db07b9743d85e4 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Sat, 25 Feb 2023 20:25:53 +1100 Subject: [PATCH 09/74] Change iOS check to use __IPHONE_16_0 for better readbility --- Sources/KIF/Classes/KIFSystemTestActor.m | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/KIF/Classes/KIFSystemTestActor.m b/Sources/KIF/Classes/KIFSystemTestActor.m index c1ae0d649..aadb9106e 100644 --- a/Sources/KIF/Classes/KIFSystemTestActor.m +++ b/Sources/KIF/Classes/KIFSystemTestActor.m @@ -58,7 +58,7 @@ - (void)simulateMemoryWarning - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation { -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 16000 +#ifdef __IPHONE_16_0 if (@available(iOS 16.0, *)) { NSSet *scenes = [[UIApplication sharedApplication] connectedScenes]; UIWindowScene* windowScene; @@ -103,7 +103,7 @@ - (void)simulateDeviceRotationToOrientation:(UIDeviceOrientation)orientation } else { #endif [[UIDevice currentDevice] setValue:@(orientation) forKey:@"orientation"]; -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 16000 +#ifdef __IPHONE_16_0 } #endif } From 7393c3f06a095e136acd0df12a45ccdd9357ac05 Mon Sep 17 00:00:00 2001 From: Bruno Mazzo Date: Sun, 26 Feb 2023 12:21:59 +1100 Subject: [PATCH 10/74] Use iPhone SE 2nd generation for tests --- .github/workflows/build.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 00051162f..adc1cb133 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -21,7 +21,7 @@ jobs: matrix: run-config: - { xcode_version: '14.1', simulator: 'name=iPad Pro (12.9-inch) (5th generation),OS=16.1' } - - { xcode_version: '14.1', simulator: 'name=iPhone SE (3nd generation),OS=16.1' } + - { xcode_version: '14.1', simulator: 'name=iPhone SE (2nd generation),OS=16.1' } steps: - name: Checkout Project uses: actions/checkout@v1 From c0ef65d93c066f50eda2bbc30b0c5f49e2b986bd Mon Sep 17 00:00:00 2001 From: Derek Ostrander Date: Tue, 21 Mar 2023 09:25:36 -0400 Subject: [PATCH 11/74] Update KIF to 3.8.8 --- KIF.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KIF.podspec b/KIF.podspec index 3b7f3e906..eaf774bed 100644 --- a/KIF.podspec +++ b/KIF.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "KIF" - s.version = "3.8.7" + s.version = "3.8.8" s.summary = "Keep It Functional - iOS UI acceptance testing in an XCUnit harness." s.homepage = "https://github.com/kif-framework/KIF/" s.license = 'Apache 2.0' From fafb26b1faeb20ccbfe3a209c5ac7f531f7d1b3f Mon Sep 17 00:00:00 2001 From: steve-sun-me <117430445+steve-sun-me@users.noreply.github.com> Date: Sat, 1 Apr 2023 16:23:34 -0700 Subject: [PATCH 12/74] Support detecting a view is offscreen (#1278) * Support detecting a view is offscreen * Added hidden view * added comments * handle scrollview is not tappable * move alpha check to a different place * Update xcode version * Update strings * Added after each * Revert "Update strings" This reverts commit 2021055a464ab599e0c2e4638919d4d715aeb7ae. * revert string changes * added more tests * revert Xcode bump * revert to original fix --- .github/workflows/build.yml | 2 +- KIF Tests/AccessibilityIdentifierTests.m | 78 +-- KIF Tests/OffscreenTests.m | 36 + KIF Tests/OffscreenTests_ViewTestActor.m | 37 ++ KIF.xcodeproj/project.pbxproj | 12 + Sources/KIF/Additions/UIView-KIFAdditions.h | 6 + Sources/KIF/Additions/UIView-KIFAdditions.m | 66 +- Sources/KIF/Classes/KIFUITestActor.m | 4 +- Sources/KIF/Classes/KIFUIViewTestActor.m | 4 +- .../Base.lproj/MainStoryboard.storyboard | 616 ++++++++++-------- Test Host/OffscreenViewController.m | 61 ++ 11 files changed, 618 insertions(+), 304 deletions(-) create mode 100644 KIF Tests/OffscreenTests.m create mode 100644 KIF Tests/OffscreenTests_ViewTestActor.m create mode 100644 Test Host/OffscreenViewController.m diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index adc1cb133..5153941ec 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -89,4 +89,4 @@ jobs: run: xcrun simctl list - name: Build & Test - run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" \ No newline at end of file + run: ./scripts/ci.sh "${{ matrix.run-config['simulator'] }}" diff --git a/KIF Tests/AccessibilityIdentifierTests.m b/KIF Tests/AccessibilityIdentifierTests.m index cafcf3676..e46ee82a6 100644 --- a/KIF Tests/AccessibilityIdentifierTests.m +++ b/KIF Tests/AccessibilityIdentifierTests.m @@ -47,29 +47,29 @@ - (void)testWaitingForAbscenceOfViewWithAccessibilityIdentifier - (void)testLongPressingViewWithAccessibilityIdentifier { - [tester tapViewWithAccessibilityIdentifier:@"idGreeting"]; - [tester longPressViewWithAccessibilityIdentifier:@"idGreeting" duration:2]; - [tester tapViewWithAccessibilityLabel:@"Select All"]; + [tester tapViewWithAccessibilityIdentifier:@"idGreeting"]; + [tester longPressViewWithAccessibilityIdentifier:@"idGreeting" duration:2]; + [tester tapViewWithAccessibilityLabel:@"Select All"]; } - (void)testEnteringTextIntoViewWithAccessibilityIdentifier { - [tester tapViewWithAccessibilityIdentifier:@"idGreeting"]; - [tester longPressViewWithAccessibilityIdentifier:@"idGreeting" duration:2]; - [tester tapViewWithAccessibilityLabel:@"Select All"]; - [tester tapViewWithAccessibilityLabel:@"Cut"]; - [tester enterText:@"Yo" intoViewWithAccessibilityIdentifier:@"idGreeting"]; + [tester tapViewWithAccessibilityIdentifier:@"idGreeting"]; + [tester longPressViewWithAccessibilityIdentifier:@"idGreeting" duration:2]; + [tester tapViewWithAccessibilityLabel:@"Select All"]; + [tester tapViewWithAccessibilityLabel:@"Cut"]; + [tester enterText:@"Yo" intoViewWithAccessibilityIdentifier:@"idGreeting"]; } - (void)testEnteringTextIntoViewWithAccessibilityIdentifierExpectingResults { - [tester enterText:@", world" intoViewWithAccessibilityIdentifier:@"idGreeting" expectedResult:@"Hello, world"]; - [tester waitForViewWithAccessibilityLabel:@"Greeting" value:@"Hello, world" traits:UIAccessibilityTraitNone]; + [tester enterText:@", world" intoViewWithAccessibilityIdentifier:@"idGreeting" expectedResult:@"Hello, world"]; + [tester waitForViewWithAccessibilityLabel:@"Greeting" value:@"Hello, world" traits:UIAccessibilityTraitNone]; } - (void)testClearingAndEnteringTextIntoViewWithAccessibilityLabel { - [tester clearTextFromAndThenEnterText:@"Yo" intoViewWithAccessibilityIdentifier:@"idGreeting"]; + [tester clearTextFromAndThenEnterText:@"Yo" intoViewWithAccessibilityIdentifier:@"idGreeting"]; } - (void)testSettingTextIntoViewWithAccessibilityIdentifier @@ -97,38 +97,38 @@ - (void)testTryFindingViewWithAccessibilityIdentifier - (void) testTappingStepperIncrement { - UILabel *uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; - NSInteger originalValue = [[uiLabel text] integerValue]; - - [tester tapStepperWithAccessibilityIdentifier:@"tapViewController.stepper" increment:(KIFStepperDirectionIncrement)]; - - [tester waitForTimeInterval:0.5f]; - uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; - NSInteger newValue = [[uiLabel text] integerValue]; - if (newValue != (originalValue + 1)) - { - NSException *exception = [NSException exceptionWithName:@"Unexpected test failure" - reason:[NSString stringWithFormat: @"newValue was expected to be +1 of originalValue. Original Value was %ld while newValue is %ld", (long)originalValue, (long)newValue] userInfo:nil]; - [tester failWithException: exception stopTest: NO]; - } + UILabel *uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; + NSInteger originalValue = [[uiLabel text] integerValue]; + + [tester tapStepperWithAccessibilityIdentifier:@"tapViewController.stepper" increment:(KIFStepperDirectionIncrement)]; + + [tester waitForTimeInterval:0.5f]; + uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; + NSInteger newValue = [[uiLabel text] integerValue]; + if (newValue != (originalValue + 1)) + { + NSException *exception = [NSException exceptionWithName:@"Unexpected test failure" + reason:[NSString stringWithFormat: @"newValue was expected to be +1 of originalValue. Original Value was %ld while newValue is %ld", (long)originalValue, (long)newValue] userInfo:nil]; + [tester failWithException: exception stopTest: NO]; + } } - (void) testTappingStepperDecrement { - UILabel *uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; - NSInteger originalValue = [[uiLabel text] integerValue]; - - [tester tapStepperWithAccessibilityIdentifier:@"tapViewController.stepper" increment:(KIFStepperDirectionDecrement)]; - - [tester waitForTimeInterval:0.5f]; - uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; - NSInteger newValue = [[uiLabel text] integerValue]; - if (newValue != (originalValue -1)) - { - NSException *exception = [NSException exceptionWithName:@"Unexpected test failure" - reason:[NSString stringWithFormat: @"newValue was expected to be -1 of originalValue. Original Value was %ld while newValue is %ld", (long)originalValue, (long)newValue] userInfo:nil]; - [tester failWithException: exception stopTest: NO]; - } + UILabel *uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; + NSInteger originalValue = [[uiLabel text] integerValue]; + + [tester tapStepperWithAccessibilityIdentifier:@"tapViewController.stepper" increment:(KIFStepperDirectionDecrement)]; + + [tester waitForTimeInterval:0.5f]; + uiLabel = (UILabel *)[tester waitForViewWithAccessibilityIdentifier:@"tapViewController.stepperValue"]; + NSInteger newValue = [[uiLabel text] integerValue]; + if (newValue != (originalValue -1)) + { + NSException *exception = [NSException exceptionWithName:@"Unexpected test failure" + reason:[NSString stringWithFormat: @"newValue was expected to be -1 of originalValue. Original Value was %ld while newValue is %ld", (long)originalValue, (long)newValue] userInfo:nil]; + [tester failWithException: exception stopTest: NO]; + } } - (void)afterEach diff --git a/KIF Tests/OffscreenTests.m b/KIF Tests/OffscreenTests.m new file mode 100644 index 000000000..cac791932 --- /dev/null +++ b/KIF Tests/OffscreenTests.m @@ -0,0 +1,36 @@ +// +// OffscreenTests.m +// KIF Tests +// +// Created by Steve Sun on 2023-03-28. +// + +#import +#import "KIFTestStepValidation.h" + +@interface OffscreenTests : KIFTestCase +@end + +@implementation OffscreenTests + +- (void)beforeEach +{ + [tester tapViewWithAccessibilityLabel:@"Offscreen Views"]; +} + +- (void)afterEach +{ + [tester tapViewWithAccessibilityLabel:@"Test Suite" traits:UIAccessibilityTraitButton]; +} + +- (void)testViewOffscreen +{ + [tester tapViewWithAccessibilityLabel:@"Scroll moving view"]; + [tester tapViewWithAccessibilityLabel:@"Move and hide views"]; + [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Out of screen view"]; + [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Alpha view"]; + [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Hidden view"]; + [tester waitForAbsenceOfViewWithAccessibilityLabel:@"Scroll moving view"]; +} + +@end diff --git a/KIF Tests/OffscreenTests_ViewTestActor.m b/KIF Tests/OffscreenTests_ViewTestActor.m new file mode 100644 index 000000000..e24064888 --- /dev/null +++ b/KIF Tests/OffscreenTests_ViewTestActor.m @@ -0,0 +1,37 @@ +// +// OffscreenTests_ViewTestActor.m +// KIF Tests +// +// Created by Steve Sun on 2023-03-31. +// + +#import +#import "KIFUITestActor.h" + +@interface OffscreenTests_ViewTestActor : KIFTestCase +@end + + +@implementation OffscreenTests_ViewTestActor + +- (void)beforeEach +{ + [[viewTester usingLabel:@"Offscreen Views"] tap]; +} + +- (void)afterEach +{ + [[[viewTester usingLabel:@"Test Suite"] usingTraits:UIAccessibilityTraitButton] tap]; +} + +- (void)testViewOffscreen +{ + [[viewTester usingLabel:@"Scroll moving view"] tap]; + [[viewTester usingLabel:@"Move and hide views"] tap]; + [[viewTester usingLabel:@"Out of screen view"] waitForAbsenceOfView]; + [[viewTester usingLabel:@"Alpha view"] waitForAbsenceOfView]; + [[viewTester usingLabel:@"Hidden view"] waitForAbsenceOfView]; + [[viewTester usingLabel:@"Scroll moving view"] waitForAbsenceOfView]; +} + +@end diff --git a/KIF.xcodeproj/project.pbxproj b/KIF.xcodeproj/project.pbxproj index b8e1dd7ff..0b14c2e9a 100644 --- a/KIF.xcodeproj/project.pbxproj +++ b/KIF.xcodeproj/project.pbxproj @@ -185,6 +185,9 @@ 85DB94731C5A5FD50025F83E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85DB94711C5A5D430025F83E /* QuartzCore.framework */; }; 85DB94741C5A5FE10025F83E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85DB94711C5A5D430025F83E /* QuartzCore.framework */; }; 85DB94751C5A5FEA0025F83E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85DB94711C5A5D430025F83E /* QuartzCore.framework */; }; + 8E654FC429D79BD8007F7811 /* OffscreenTests_ViewTestActor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E654FC329D79BD8007F7811 /* OffscreenTests_ViewTestActor.m */; }; + 8EAA1EE229D3AF7A008F6029 /* OffscreenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EAA1EE129D3AF7A008F6029 /* OffscreenViewController.m */; }; + 8EAA1EE429D3B1F5008F6029 /* OffscreenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EAA1EE329D3B1F5008F6029 /* OffscreenTests.m */; }; 97E8A5CF1B0A62F700124E3B /* BackgroundViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97E8A5CE1B0A62F700124E3B /* BackgroundViewController.m */; }; 97E8A5D11B0A63D100124E3B /* BackgroundTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 97E8A5D01B0A63D100124E3B /* BackgroundTests.m */; }; 9CC881A91AD4CE39002CD34C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAB072B413971AEA008AF393 /* UIKit.framework */; }; @@ -401,6 +404,9 @@ 84D293B01A2C891700C10944 /* SystemAlertTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SystemAlertTests.m; sourceTree = ""; }; 84D293B71A2C8DF700C10944 /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; 85DB94711C5A5D430025F83E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 8E654FC329D79BD8007F7811 /* OffscreenTests_ViewTestActor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenTests_ViewTestActor.m; sourceTree = ""; }; + 8EAA1EE129D3AF7A008F6029 /* OffscreenViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenViewController.m; sourceTree = ""; }; + 8EAA1EE329D3B1F5008F6029 /* OffscreenTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenTests.m; sourceTree = ""; }; 97E8A5CE1B0A62F700124E3B /* BackgroundViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BackgroundViewController.m; sourceTree = ""; }; 97E8A5D01B0A63D100124E3B /* BackgroundTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BackgroundTests.m; sourceTree = ""; }; 9CC881A21AD4CAAC002CD34C /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; @@ -801,6 +807,7 @@ 84D293AC1A2C84F700C10944 /* SystemAlertViewController.m */, 97E8A5CE1B0A62F700124E3B /* BackgroundViewController.m */, EB60ECC7177F8C83005A041A /* Supporting Files */, + 8EAA1EE129D3AF7A008F6029 /* OffscreenViewController.m */, ); path = "Test Host"; sourceTree = ""; @@ -856,6 +863,7 @@ 5F6A1B371C191F9600F20F22 /* UIApplicationKIFAdditionsTests.m */, B66B1BF3202BC94F00D0E4B2 /* AutocorrectTests.m */, EB60ECF0177F8DB3005A041A /* Supporting Files */, + 8EAA1EE329D3B1F5008F6029 /* OffscreenTests.m */, ); path = "KIF Tests"; sourceTree = ""; @@ -897,6 +905,7 @@ FA8A3C5E1A772E6800206350 /* AccessibilityIdentifierTests_ViewTestActor.m */, FA8A3C5A1A77281900206350 /* WebViewTests_ViewTestActor.m */, FA8A3C601A77320000206350 /* SystemAlertTests_ViewTestActor.m */, + 8E654FC329D79BD8007F7811 /* OffscreenTests_ViewTestActor.m */, ); name = "KIFUIViewTestActor Tests"; sourceTree = ""; @@ -1353,6 +1362,7 @@ FA8A3C551A77157F00206350 /* LongPressTests_ViewTestActor.m in Sources */, FA49155E1A78206E00A78E57 /* CompositionTests_ViewTestActor.m in Sources */, FA8A3C5F1A772E6800206350 /* AccessibilityIdentifierTests_ViewTestActor.m in Sources */, + 8E654FC429D79BD8007F7811 /* OffscreenTests_ViewTestActor.m in Sources */, FA8A3C5D1A772CD100206350 /* WaitForAbscenceTests_ViewTestActor.m in Sources */, FA8A3C5B1A77281900206350 /* WebViewTests_ViewTestActor.m in Sources */, EABD46B11857A0F300A5F081 /* SearchFieldTests.m in Sources */, @@ -1382,6 +1392,7 @@ FA4915691A78449C00A78E57 /* CollectionViewTests_ViewTestActor.m in Sources */, FA8DA74F1A7711E900E0C644 /* WaitForTappableViewTests_ViewTestActor.m in Sources */, EABD46BA1857A0F300A5F081 /* WaitForAbscenceTests.m in Sources */, + 8EAA1EE429D3B1F5008F6029 /* OffscreenTests.m in Sources */, EA47DA2818EDFD6F0034D2F5 /* CollectionViewTests.m in Sources */, EABD46BB1857A0F300A5F081 /* WaitForTappableViewTests.m in Sources */, EABD46BC1857A0F300A5F081 /* WaitForViewTests.m in Sources */, @@ -1425,6 +1436,7 @@ 2CDEE1CB181DBED200DF6E63 /* PickerController.m in Sources */, EB60ED03177F9032005A041A /* TestSuiteViewController.m in Sources */, D9EA274318F05A6700D87E57 /* ScrollViewController.m in Sources */, + 8EAA1EE229D3AF7A008F6029 /* OffscreenViewController.m in Sources */, 3812FB611A1212A700335733 /* AnimationViewController.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Sources/KIF/Additions/UIView-KIFAdditions.h b/Sources/KIF/Additions/UIView-KIFAdditions.h index d04818b22..acb481876 100644 --- a/Sources/KIF/Additions/UIView-KIFAdditions.h +++ b/Sources/KIF/Additions/UIView-KIFAdditions.h @@ -102,6 +102,12 @@ typedef CGPoint KIFDisplacement; */ - (BOOL)isVisibleInWindowFrame; +/*! + @abstract Evaluates if the view is within visible or scrollable range. + @discussion A view can be offscreen completely so we consider this as NOT visible in window. + */ +- (BOOL)isPossiblyVisibleInWindow; + /*! @method performBlockOnDescendentViews: @abstract Calls a block on the view itself and on all its descendent views. diff --git a/Sources/KIF/Additions/UIView-KIFAdditions.m b/Sources/KIF/Additions/UIView-KIFAdditions.m index 8719057d0..4d7b31c3f 100644 --- a/Sources/KIF/Additions/UIView-KIFAdditions.m +++ b/Sources/KIF/Additions/UIView-KIFAdditions.m @@ -135,6 +135,47 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi return [self accessibilityElementMatchingBlock:matchBlock notHidden:YES]; } +- (BOOL)isPossiblyVisibleInWindow +{ + if (self.alpha == 0) { + return NO; + } + + if ([self isVisibleInWindowFrame]) { + return YES; + } else { + // This is a fix when a view is not hidden but outside of visible area and scrollable content size + // + // scroll view scrollable content + // ------------- + // | | + // |scrollView | View is not hidden and it's out of the scollable content + // | | ----- + // | | | | <- a subview of the scrollView + // | | | | + // ------------- ----- + // + // We want to detect that if the view is there but it's out of the scrollable content size + // If it's out of the scrollable content size, we consider as not visible + // + // We are only interested if the parent is a scrollView and NOT collectionView and NOT tableView + UIScrollView *scrollView = (UIScrollView *)[self ancestorScrollView]; + // if scrollView is within a tappable point, that means we can check to see if `self` is viewable within content size + // + // TODO: We haven't handled if a scrollView is inside another scrollView + if (scrollView && scrollView.isTappable) { + CGSize scrollViewSize = scrollView.contentSize; + BOOL isXVisible = scrollViewSize.width >= self.frame.origin.x; + BOOL isYVisible = scrollViewSize.height >= self.frame.origin.y; + BOOL isSelfVisible = isXVisible && isYVisible; + + return isSelfVisible; + } + + return NO; + } +} + - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessibilityElement *))matchBlock notHidden:(BOOL)notHidden; { if (notHidden && self.hidden) { @@ -322,7 +363,7 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi if ([indexPathsForVisibleItems containsObject:indexPath]) { continue; } - + @autoreleasepool { // Get the cell directly from the dataSource because UICollectionView will only vend visible cells UICollectionViewCell *cell = [collectionView.dataSource collectionView:collectionView cellForItemAtIndexPath:indexPath]; @@ -356,7 +397,7 @@ - (UIAccessibilityElement *)accessibilityElementMatchingBlock:(BOOL(^)(UIAccessi } } } - + return matchingButOccludedElement; } @@ -1053,7 +1094,8 @@ - (void)performBlockOnAscendentViews:(void (^)(UIView *view, BOOL *stop))block } } --(UIView*)tryGetiOS16KeyboardFallbackViewFromParentView:(UIView*) parentView { +- (UIView *)tryGetiOS16KeyboardFallbackViewFromParentView:(UIView*) parentView +{ if([parentView isKindOfClass:NSClassFromString(@"_UIRemoteKeyboardPlaceholderView")]) { UIView* fallbackView = [parentView valueForKey:@"_fallbackView"]; return fallbackView; @@ -1062,4 +1104,22 @@ -(UIView*)tryGetiOS16KeyboardFallbackViewFromParentView:(UIView*) parentView { return nil; } +- (nullable UIView *)ancestorScrollView +{ + // We don't want collection view and table view because we handle them separately. + // This function is only getting a plain scroll view + UIView *currentSuperview = self.superview; + while (currentSuperview != nil) { + if ([currentSuperview isKindOfClass:[UIScrollView class]] && + ![currentSuperview isKindOfClass:[UICollectionView class]] && + ![currentSuperview isKindOfClass:[UITableView class]]) { + return currentSuperview; + } + + currentSuperview = currentSuperview.superview; + } + + return nil; +} + @end diff --git a/Sources/KIF/Classes/KIFUITestActor.m b/Sources/KIF/Classes/KIFUITestActor.m index a79d8ff80..ff8c9ca15 100644 --- a/Sources/KIF/Classes/KIFUITestActor.m +++ b/Sources/KIF/Classes/KIFUITestActor.m @@ -177,7 +177,7 @@ - (void)waitForAbsenceOfViewWithAccessibilityLabel:(NSString *)label value:(NSSt KIFTestWaitCondition(view, error, @"Cannot find view containing accessibility element with the label \"%@\"", label); // Hidden views count as absent - KIFTestWaitCondition([view isHidden] || [view superview] == nil, error, @"Accessibility element %@ with label \"%@\" is visible and not hidden.", view, label); + KIFTestWaitCondition([view isHidden] || [view superview] == nil || ![view isPossiblyVisibleInWindow], error, @"Accessibility element %@ with label \"%@\" is visible and not hidden.", view, label); return KIFTestStepResultSuccess; }]; @@ -200,7 +200,7 @@ - (void)waitForAbsenceOfViewWithElementMatchingPredicate:(NSPredicate *)predicat KIFTestWaitCondition(view, error, @"Cannot find view containing accessibility element with the predicate \"%@\"", predicate); // Hidden views count as absent - KIFTestWaitCondition([view isHidden] || [view superview] == nil, error, @"Accessibility element with predicate \"%@\" is visible and not hidden.", predicate); + KIFTestWaitCondition([view isHidden] || [view superview] == nil || ![view isPossiblyVisibleInWindow], error, @"Accessibility element with predicate \"%@\" is visible and not hidden.", predicate); return KIFTestStepResultSuccess; }]; diff --git a/Sources/KIF/Classes/KIFUIViewTestActor.m b/Sources/KIF/Classes/KIFUIViewTestActor.m index 012e86916..5039f75a0 100644 --- a/Sources/KIF/Classes/KIFUIViewTestActor.m +++ b/Sources/KIF/Classes/KIFUIViewTestActor.m @@ -197,8 +197,8 @@ - (void)waitForAbsenceOfView; KIFTestWaitCondition(found.view, error, @"Cannot find view containing accessibility element \"%@\"", found.element); // Hidden views count as absent - KIFTestWaitCondition([found.view isHidden] || [found.view superview] == nil, error, @"Accessibility element \"%@\" is visible and not hidden.", found); - + KIFTestWaitCondition([found.view isHidden] || [found.view superview] == nil || ![found.view isPossiblyVisibleInWindow], error, @"Accessibility element \"%@\" is visible and not hidden.", found); + return KIFTestStepResultSuccess; }]; } diff --git a/Test Host/Base.lproj/MainStoryboard.storyboard b/Test Host/Base.lproj/MainStoryboard.storyboard index 3b2a46cb7..1235360bd 100644 --- a/Test Host/Base.lproj/MainStoryboard.storyboard +++ b/Test Host/Base.lproj/MainStoryboard.storyboard @@ -1,9 +1,10 @@ - + - + + @@ -12,7 +13,7 @@ - + @@ -35,24 +36,24 @@ - + - + - + @@ -63,17 +64,17 @@ - + - + @@ -84,17 +85,17 @@ - + - + @@ -105,17 +106,17 @@ - + - + @@ -126,17 +127,17 @@ - + - + @@ -147,17 +148,17 @@ - + - + @@ -168,17 +169,17 @@ - + - + @@ -188,17 +189,17 @@ - + - + @@ -208,17 +209,17 @@ - + - + @@ -228,17 +229,17 @@ - + - + @@ -247,22 +248,42 @@ + + + + + + + + + + + + + + - + - + @@ -270,17 +291,17 @@ - + - + @@ -290,17 +311,17 @@ - + - + @@ -308,17 +329,17 @@ - + - + @@ -367,14 +388,14 @@ - + @@ -394,7 +415,7 @@ - + @@ -406,7 +427,7 @@ - + @@ -416,14 +437,14 @@ - + - + @@ -438,7 +459,7 @@ - + @@ -459,7 +480,7 @@ - + @@ -469,14 +490,14 @@ - + - + @@ -486,14 +507,14 @@ - + - + @@ -503,14 +524,14 @@ - + - + @@ -520,14 +541,14 @@ - + - + @@ -537,14 +558,14 @@ - + - + @@ -554,14 +575,14 @@ - + - + @@ -571,14 +592,14 @@ - + - + @@ -588,14 +609,14 @@ - + - + @@ -605,14 +626,14 @@ - + - + @@ -622,14 +643,14 @@ - + - + @@ -639,14 +660,14 @@ - + - + @@ -656,449 +677,449 @@ - + - + - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - - + - @@ -1109,13 +1130,13 @@ - + - - - - + - - - + - - + @@ -1547,10 +1568,10 @@ - + - - - - + + + + + + + + + + + + + + + + + + + + + + + @@ -1980,14 +2065,14 @@ Line Break - + @@ -2005,4 +2090,21 @@ Line Break + + + + + + + + + + + + + + + + + diff --git a/Test Host/OffscreenViewController.m b/Test Host/OffscreenViewController.m new file mode 100644 index 000000000..45aeca1d5 --- /dev/null +++ b/Test Host/OffscreenViewController.m @@ -0,0 +1,61 @@ +// +// OffscreenViewController.m +// Test Host +// +// Created by Steve Sun on 2023-03-28. +// + +@interface OffscreenViewController : UIViewController +@property (weak, nonatomic) IBOutlet UIView *alphaView; +@property (weak, nonatomic) IBOutlet UIView *movingView; +@property (weak, nonatomic) IBOutlet UIScrollView *scrollView; +@property (weak, nonatomic) IBOutlet UIView *hiddenView; + +@property (strong, nonatomic) UIView *scrollMovingView; +@end + +@implementation OffscreenViewController + +- (void)viewDidLoad +{ + [super viewDidLoad]; + self.scrollView.accessibilityLabel = @"Scroll View"; + self.scrollView.contentInset = UIEdgeInsetsMake(2000, 2000, 0, 0); + self.scrollView.contentSize = CGSizeMake(2000, 2000); + self.scrollView.delegate = self; + + self.scrollMovingView = [UIView new]; + self.scrollMovingView.frame = CGRectMake(1000, 500, 100, 100); + self.scrollMovingView.backgroundColor = [UIColor systemPinkColor]; + self.scrollMovingView.accessibilityLabel = @"Scroll moving view"; + + [self.scrollView addSubview:self.scrollMovingView]; +} + +- (IBAction)hideAndMoveViewsTapped:(UIButton *)sender +{ + CGRect screenRect = [[UIScreen mainScreen] bounds]; + + [UIView animateWithDuration:0.5 delay:0 options:UIViewAnimationOptionCurveEaseInOut animations:^{ + self.movingView.frame = CGRectMake(screenRect.size.width + 10, + self.movingView.frame.origin.y, + self.movingView.frame.size.width, + self.movingView.frame.size.height); + self.scrollMovingView.frame = CGRectMake(50000, + self.scrollMovingView.frame.origin.y, + self.scrollMovingView.frame.size.width, + self.scrollMovingView.frame.size.height); + self.alphaView.alpha = 0; + [self.hiddenView setHidden:YES]; + } completion:^(BOOL finished) {}]; + +} + +#pragma mark UIScrollViewDelegate Methods + +- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView +{ + return scrollView; +} + +@end From 4081d3ffa268236a2022d77717e0d6c4099609fb Mon Sep 17 00:00:00 2001 From: steve-sun-me <117430445+steve-sun-me@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:10:39 -0700 Subject: [PATCH 13/74] Set animation speed for all windows (#1279) * Set animation speed for all windows * remove nslog * rename * rename * Swizzle init * change testing code back * set project level --- KIF.xcodeproj/project.pbxproj | 24 ++++++++++ Sources/KIF/Additions/NSObject+KIFSwizzle.h | 14 ++++++ Sources/KIF/Additions/NSObject+KIFSwizzle.m | 23 +++++++++ .../Additions/UIApplication-KIFAdditions.m | 4 +- Sources/KIF/Additions/UIWindow+KIFSwizzle.h | 12 +++++ Sources/KIF/Additions/UIWindow+KIFSwizzle.m | 48 +++++++++++++++++++ 6 files changed, 124 insertions(+), 1 deletion(-) create mode 100644 Sources/KIF/Additions/NSObject+KIFSwizzle.h create mode 100644 Sources/KIF/Additions/NSObject+KIFSwizzle.m create mode 100644 Sources/KIF/Additions/UIWindow+KIFSwizzle.h create mode 100644 Sources/KIF/Additions/UIWindow+KIFSwizzle.m diff --git a/KIF.xcodeproj/project.pbxproj b/KIF.xcodeproj/project.pbxproj index 0b14c2e9a..0dd2ab00e 100644 --- a/KIF.xcodeproj/project.pbxproj +++ b/KIF.xcodeproj/project.pbxproj @@ -186,8 +186,16 @@ 85DB94741C5A5FE10025F83E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85DB94711C5A5D430025F83E /* QuartzCore.framework */; }; 85DB94751C5A5FEA0025F83E /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 85DB94711C5A5D430025F83E /* QuartzCore.framework */; }; 8E654FC429D79BD8007F7811 /* OffscreenTests_ViewTestActor.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E654FC329D79BD8007F7811 /* OffscreenTests_ViewTestActor.m */; }; + 8E654FCE29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E654FCC29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h */; }; + 8E654FCF29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8E654FCC29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h */; }; + 8E654FD029DA2FE7007F7811 /* UIWindow+KIFSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E654FCD29DA2FE7007F7811 /* UIWindow+KIFSwizzle.m */; }; + 8E654FD129DA2FE8007F7811 /* UIWindow+KIFSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8E654FCD29DA2FE7007F7811 /* UIWindow+KIFSwizzle.m */; }; 8EAA1EE229D3AF7A008F6029 /* OffscreenViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EAA1EE129D3AF7A008F6029 /* OffscreenViewController.m */; }; 8EAA1EE429D3B1F5008F6029 /* OffscreenTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EAA1EE329D3B1F5008F6029 /* OffscreenTests.m */; }; + 8EC2CB1F29DB3D3B001BE493 /* NSObject+KIFSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC2CB1D29DB3D3B001BE493 /* NSObject+KIFSwizzle.h */; }; + 8EC2CB2029DB3D3B001BE493 /* NSObject+KIFSwizzle.h in Headers */ = {isa = PBXBuildFile; fileRef = 8EC2CB1D29DB3D3B001BE493 /* NSObject+KIFSwizzle.h */; }; + 8EC2CB2129DB3D3B001BE493 /* NSObject+KIFSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC2CB1E29DB3D3B001BE493 /* NSObject+KIFSwizzle.m */; }; + 8EC2CB2229DB3D3B001BE493 /* NSObject+KIFSwizzle.m in Sources */ = {isa = PBXBuildFile; fileRef = 8EC2CB1E29DB3D3B001BE493 /* NSObject+KIFSwizzle.m */; }; 97E8A5CF1B0A62F700124E3B /* BackgroundViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 97E8A5CE1B0A62F700124E3B /* BackgroundViewController.m */; }; 97E8A5D11B0A63D100124E3B /* BackgroundTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 97E8A5D01B0A63D100124E3B /* BackgroundTests.m */; }; 9CC881A91AD4CE39002CD34C /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = AAB072B413971AEA008AF393 /* UIKit.framework */; }; @@ -405,8 +413,12 @@ 84D293B71A2C8DF700C10944 /* AddressBookUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AddressBookUI.framework; path = System/Library/Frameworks/AddressBookUI.framework; sourceTree = SDKROOT; }; 85DB94711C5A5D430025F83E /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; 8E654FC329D79BD8007F7811 /* OffscreenTests_ViewTestActor.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenTests_ViewTestActor.m; sourceTree = ""; }; + 8E654FCC29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "UIWindow+KIFSwizzle.h"; sourceTree = ""; }; + 8E654FCD29DA2FE7007F7811 /* UIWindow+KIFSwizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "UIWindow+KIFSwizzle.m"; sourceTree = ""; }; 8EAA1EE129D3AF7A008F6029 /* OffscreenViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenViewController.m; sourceTree = ""; }; 8EAA1EE329D3B1F5008F6029 /* OffscreenTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = OffscreenTests.m; sourceTree = ""; }; + 8EC2CB1D29DB3D3B001BE493 /* NSObject+KIFSwizzle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "NSObject+KIFSwizzle.h"; sourceTree = ""; }; + 8EC2CB1E29DB3D3B001BE493 /* NSObject+KIFSwizzle.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "NSObject+KIFSwizzle.m"; sourceTree = ""; }; 97E8A5CE1B0A62F700124E3B /* BackgroundViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BackgroundViewController.m; sourceTree = ""; }; 97E8A5D01B0A63D100124E3B /* BackgroundTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = BackgroundTests.m; sourceTree = ""; }; 9CC881A21AD4CAAC002CD34C /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; @@ -651,6 +663,10 @@ 2229D54E25BEF47D0093296C /* UIWindow-KIFAdditions.m */, 2229D56E25BEF47D0093296C /* XCTestCase-KIFAdditions.h */, 2229D55C25BEF47D0093296C /* XCTestCase-KIFAdditions.m */, + 8E654FCC29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h */, + 8E654FCD29DA2FE7007F7811 /* UIWindow+KIFSwizzle.m */, + 8EC2CB1D29DB3D3B001BE493 /* NSObject+KIFSwizzle.h */, + 8EC2CB1E29DB3D3B001BE493 /* NSObject+KIFSwizzle.m */, ); name = Additions; path = Sources/KIF/Additions; @@ -972,6 +988,7 @@ 22B1376C25D6E32700D88061 /* KIFTestCase.h in Headers */, 22B1373225D6E32700D88061 /* KIFUITestActor_Private.h in Headers */, 22B1375725D6E32700D88061 /* KIFUIObject.h in Headers */, + 8E654FCF29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h in Headers */, 22B1375525D6E32700D88061 /* KIFUIViewTestActor.h in Headers */, 22B1375B25D6E32700D88061 /* CAAnimation+KIFAdditions.h in Headers */, 22B1375225D6E32700D88061 /* NSPredicate+KIFAdditions.h in Headers */, @@ -980,6 +997,7 @@ 22B1376225D6E32700D88061 /* UITableView-KIFAdditions.h in Headers */, 9CC967401AD4B1B600576D13 /* KIF.h in Headers */, 22B1373525D6E32700D88061 /* UIDatePicker+KIFAdditions.h in Headers */, + 8EC2CB2029DB3D3B001BE493 /* NSObject+KIFSwizzle.h in Headers */, 22B1376F25D6E32700D88061 /* KIFTestActor_Private.h in Headers */, 22B1375025D6E32700D88061 /* KIFTouchVisualizerView.h in Headers */, 22B1377925D6E32700D88061 /* KIFSystemTestActor.h in Headers */, @@ -1015,6 +1033,7 @@ 2229D5DE25BEF47D0093296C /* KIF.h in Headers */, 2229D5CE25BEF47D0093296C /* KIFTypist.h in Headers */, 2229D5A725BEF47D0093296C /* UITableView-KIFAdditions.h in Headers */, + 8EC2CB1F29DB3D3B001BE493 /* NSObject+KIFSwizzle.h in Headers */, 2229D5AB25BEF47D0093296C /* NSError-KIFAdditions.h in Headers */, 2229D5B825BEF47D0093296C /* UIScreen+KIFAdditions.h in Headers */, 2229D5AA25BEF47D0093296C /* UIView-KIFAdditions.h in Headers */, @@ -1029,6 +1048,7 @@ 2229D5B625BEF47D0093296C /* NSString+KIFAdditions.h in Headers */, 2229D5BC25BEF47D0093296C /* CAAnimation+KIFAdditions.h in Headers */, 2229D59525BEF47D0093296C /* KIFUITestActor-IdentifierTests.h in Headers */, + 8E654FCE29DA2FE7007F7811 /* UIWindow+KIFSwizzle.h in Headers */, 2229D59925BEF47D0093296C /* KIFTouchVisualizerView.h in Headers */, 2229D5C525BEF47D0093296C /* NSBundle-KIFAdditions.h in Headers */, 2229D59B25BEF47D0093296C /* KIFTouchVisualizerViewCoordinator.h in Headers */, @@ -1276,6 +1296,7 @@ 22B1375F25D6E32700D88061 /* KIFTextInputTraitsOverrides.m in Sources */, 22B1375925D6E32700D88061 /* NSError-KIFAdditions.m in Sources */, 22B1377025D6E32700D88061 /* CAAnimation+KIFAdditions.m in Sources */, + 8E654FD129DA2FE8007F7811 /* UIWindow+KIFSwizzle.m in Sources */, 22B1373325D6E32700D88061 /* NSPredicate+KIFAdditions.m in Sources */, 22B1376E25D6E32700D88061 /* IOHIDEvent+KIF.m in Sources */, 22B1375D25D6E32700D88061 /* UITableView-KIFAdditions.m in Sources */, @@ -1304,6 +1325,7 @@ 22B1373A25D6E32700D88061 /* KIFUIObject.m in Sources */, 22B1377425D6E32700D88061 /* KIFTestActor.m in Sources */, 22B1374C25D6E32700D88061 /* UIApplication-KIFAdditions.m in Sources */, + 8EC2CB2229DB3D3B001BE493 /* NSObject+KIFSwizzle.m in Sources */, 22B1375C25D6E32700D88061 /* KIFUITestActor-ConditionalTests.m in Sources */, 22B1376525D6E32700D88061 /* KIFTypist.m in Sources */, ); @@ -1321,6 +1343,7 @@ 2229D59725BEF47D0093296C /* KIFTouchVisualizerViewCoordinator.m in Sources */, 2229D5B125BEF47D0093296C /* XCTestCase-KIFAdditions.m in Sources */, 2229D5A225BEF47D0093296C /* CGGeometry-KIFAdditions.m in Sources */, + 8E654FD029DA2FE7007F7811 /* UIWindow+KIFSwizzle.m in Sources */, 2229D5BE25BEF47D0093296C /* UITableView-KIFAdditions.m in Sources */, 2229D5AF25BEF47D0093296C /* NSBundle-KIFAdditions.m in Sources */, 2229D59C25BEF47D0093296C /* KIFTouchVisualizerView.m in Sources */, @@ -1349,6 +1372,7 @@ 2229D5D925BEF47D0093296C /* KIFTestStepValidation.m in Sources */, 2229D5A525BEF47D0093296C /* UIView-Debugging.m in Sources */, 2229D5C125BEF47D0093296C /* NSError-KIFAdditions.m in Sources */, + 8EC2CB2129DB3D3B001BE493 /* NSObject+KIFSwizzle.m in Sources */, 2229D5B525BEF47D0093296C /* UIApplication-KIFAdditions.m in Sources */, 2229D5C025BEF47D0093296C /* UIEvent+KIFAdditions.m in Sources */, ); diff --git a/Sources/KIF/Additions/NSObject+KIFSwizzle.h b/Sources/KIF/Additions/NSObject+KIFSwizzle.h new file mode 100644 index 000000000..2267c48ea --- /dev/null +++ b/Sources/KIF/Additions/NSObject+KIFSwizzle.h @@ -0,0 +1,14 @@ +// +// NSObject+KIFSwizzle.h +// KIF +// +// Created by Steve Sun on 2023-04-03. +// + +#import + +@interface NSObject (KIFSwizzle) + ++ (void)swizzleSEL:(SEL)originalSEL withSEL:(SEL)swizzledSEL; + +@end diff --git a/Sources/KIF/Additions/NSObject+KIFSwizzle.m b/Sources/KIF/Additions/NSObject+KIFSwizzle.m new file mode 100644 index 000000000..dfcbd9788 --- /dev/null +++ b/Sources/KIF/Additions/NSObject+KIFSwizzle.m @@ -0,0 +1,23 @@ +// +// NSObject+KIFSwizzle.m +// KIF +// +// Created by Steve Sun on 2023-04-03. +// + +#import "NSObject+KIFSwizzle.h" +#import + +@implementation NSObject (KIFSwizzle) + ++ (void)swizzleSEL:(SEL)originalSEL withSEL:(SEL)swizzledSEL +{ + Class class = [self class]; + + Method originalMethod = class_getInstanceMethod(class, originalSEL); + Method swizzledMethod = class_getInstanceMethod(class, swizzledSEL); + + method_exchangeImplementations(originalMethod, swizzledMethod); +} + +@end diff --git a/Sources/KIF/Additions/UIApplication-KIFAdditions.m b/Sources/KIF/Additions/UIApplication-KIFAdditions.m index e02cfe1c9..cbc3e5fe9 100644 --- a/Sources/KIF/Additions/UIApplication-KIFAdditions.m +++ b/Sources/KIF/Additions/UIApplication-KIFAdditions.m @@ -147,7 +147,9 @@ - (float)animationSpeed - (void)setAnimationSpeed:(float)animationSpeed { - self.keyWindow.layer.speed = animationSpeed; + for (UIWindow *window in self.windows) { + window.layer.speed = animationSpeed; + } } #pragma mark - Screenshotting diff --git a/Sources/KIF/Additions/UIWindow+KIFSwizzle.h b/Sources/KIF/Additions/UIWindow+KIFSwizzle.h new file mode 100644 index 000000000..e03d4857e --- /dev/null +++ b/Sources/KIF/Additions/UIWindow+KIFSwizzle.h @@ -0,0 +1,12 @@ +// +// UIWindow+KIFAdditions.h +// KIF +// +// Created by Steve Sun on 2023-04-02. +// + +#import + +@interface UIWindow (KIFSwizzle) + +@end diff --git a/Sources/KIF/Additions/UIWindow+KIFSwizzle.m b/Sources/KIF/Additions/UIWindow+KIFSwizzle.m new file mode 100644 index 000000000..9273fae6b --- /dev/null +++ b/Sources/KIF/Additions/UIWindow+KIFSwizzle.m @@ -0,0 +1,48 @@ +// +// UIWindow+KIFAdditions.m +// KIF +// +// Created by Steve Sun on 2023-04-02. +// + +#import "UIWindow+KIFSwizzle.h" +#import "UIApplication-KIFAdditions.h" +#import "NSObject+KIFSwizzle.h" + +@implementation UIWindow (KIFSwizzle) + ++ (void)load +{ + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + [self swizzleSEL:@selector(init) withSEL:@selector(swizzle_init)]; + [self swizzleSEL:@selector(becomeKeyWindow) withSEL:@selector(swizzle_becomeKeyWindow)]; + if (@available(iOS 13.0, *)) { + [self swizzleSEL:@selector(initWithWindowScene:) withSEL:@selector(swizzle_initWithWindowScene:)]; + } + }); +} + +- (instancetype)swizzle_initWithWindowScene:(UIWindowScene *)scene API_AVAILABLE(ios(13)) +{ + UIWindow *window = [self swizzle_initWithWindowScene:scene]; + window.layer.speed = [UIApplication sharedApplication].animationSpeed; + + return window; +} + +- (instancetype)swizzle_init +{ + UIWindow *window = [self swizzle_init]; + window.layer.speed = [UIApplication sharedApplication].animationSpeed; + + return window; +} + +- (void)swizzle_becomeKeyWindow +{ + [self swizzle_becomeKeyWindow]; + self.layer.speed = [UIApplication sharedApplication].animationSpeed; +} + +@end From 6c3ff27d9449eab614dae63e571596e4982a5205 Mon Sep 17 00:00:00 2001 From: steve-sun-me <117430445+steve-sun-me@users.noreply.github.com> Date: Mon, 3 Apr 2023 15:14:11 -0700 Subject: [PATCH 14/74] Update KIF to 3.8.9 (#1280) --- KIF.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/KIF.podspec b/KIF.podspec index eaf774bed..40c0c37a2 100644 --- a/KIF.podspec +++ b/KIF.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "KIF" - s.version = "3.8.8" + s.version = "3.8.9" s.summary = "Keep It Functional - iOS UI acceptance testing in an XCUnit harness." s.homepage = "https://github.com/kif-framework/KIF/" s.license = 'Apache 2.0' From 61a4715331fddd4c7526148bd5c3aacaaff37acc Mon Sep 17 00:00:00 2001 From: Daniel Ornelas Date: Mon, 1 May 2023 13:01:57 -0700 Subject: [PATCH 15/74] Bump ios minimum deployment target to 11.0 --- KIF.xcodeproj/project.pbxproj | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/KIF.xcodeproj/project.pbxproj b/KIF.xcodeproj/project.pbxproj index 0dd2ab00e..bd4696781 100644 --- a/KIF.xcodeproj/project.pbxproj +++ b/KIF.xcodeproj/project.pbxproj @@ -1789,7 +1789,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; SDKROOT = iphoneos; @@ -1834,7 +1834,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; @@ -2097,7 +2097,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 11.0; PUBLIC_HEADERS_FOLDER_PATH = "include/$(PRODUCT_NAME)"; SDKROOT = iphoneos; SKIP_INSTALL = YES; From 3eb917baae02356c66d13a241af5408f907b93c2 Mon Sep 17 00:00:00 2001 From: Daniel Ornelas Date: Sat, 6 May 2023 23:21:19 -0700 Subject: [PATCH 16/74] Fixing tests to compile with iOS11 --- KIF Tests/ModalViewTests.m | 4 +- KIF Tests/ModalViewTests_ViewTestActor.m | 4 +- KIF Tests/SystemTests.m | 43 ------------------- .../Base.lproj/MainStoryboard.storyboard | 6 +-- Test Host/TestSuiteViewController.m | 39 ++++++++++++++--- 5 files changed, 41 insertions(+), 55 deletions(-) diff --git a/KIF Tests/ModalViewTests.m b/KIF Tests/ModalViewTests.m index cdee7f768..330a9413d 100644 --- a/KIF Tests/ModalViewTests.m +++ b/KIF Tests/ModalViewTests.m @@ -31,8 +31,8 @@ - (void)testInteractionWithAnAlertView - (void)testInteractionWithAnActionSheet { - [tester tapViewWithAccessibilityLabel:@"UIActionSheet"]; - [tester waitForViewWithAccessibilityLabel:@"Action Sheet"]; + [tester tapViewWithAccessibilityLabel:@"UIAlertController"]; + [tester waitForViewWithAccessibilityLabel:@"Alert Controller"]; [tester waitForTappableViewWithAccessibilityLabel:@"Destroy"]; [tester waitForTappableViewWithAccessibilityLabel:@"A"]; [tester waitForTappableViewWithAccessibilityLabel:@"B"]; diff --git a/KIF Tests/ModalViewTests_ViewTestActor.m b/KIF Tests/ModalViewTests_ViewTestActor.m index a885755ab..b6e63bf58 100644 --- a/KIF Tests/ModalViewTests_ViewTestActor.m +++ b/KIF Tests/ModalViewTests_ViewTestActor.m @@ -31,8 +31,8 @@ - (void)testInteractionWithAnAlertView - (void)testInteractionWithAnActionSheet { - [[viewTester usingLabel:@"UIActionSheet"] tap]; - [[viewTester usingLabel:@"Action Sheet"] waitForView]; + [[viewTester usingLabel:@"UIAlertController"] tap]; + [[viewTester usingLabel:@"Alert Controller"] waitForView]; [[viewTester usingLabel:@"Destroy"] waitForTappableView]; [[viewTester usingLabel:@"A"] waitForTappableView]; [[viewTester usingLabel:@"B"] waitForTappableView]; diff --git a/KIF Tests/SystemTests.m b/KIF Tests/SystemTests.m index bf695de11..9973261c5 100644 --- a/KIF Tests/SystemTests.m +++ b/KIF Tests/SystemTests.m @@ -63,48 +63,6 @@ - (void)testMemoryWarningSimulator } - (void)testMockingOpenURL -{ - __block BOOL openURLReturnValue; - __block BOOL canOpenURLReturnValue; - [system waitForApplicationToOpenURL:@"test123://" whileExecutingBlock:^{ - NSURL *uninstalledAppURL = [NSURL URLWithString:@"test123://"]; - canOpenURLReturnValue = [[UIApplication sharedApplication] canOpenURL:uninstalledAppURL]; - openURLReturnValue = [[UIApplication sharedApplication] openURL:uninstalledAppURL]; - } returning:NO]; - KIFAssertEqual(NO, openURLReturnValue, @"openURL: should have returned NO"); - KIFAssertEqual(NO, canOpenURLReturnValue, @"canOpenURL: should have returned NO"); - - [system waitForApplicationToOpenURL:@"test123://" whileExecutingBlock:^{ - NSURL *installedAppURL = [NSURL URLWithString:@"test123://"]; - canOpenURLReturnValue = [[UIApplication sharedApplication] canOpenURL:installedAppURL]; - openURLReturnValue = [[UIApplication sharedApplication] openURL:installedAppURL]; - } returning:YES]; - KIFAssertEqual(YES, openURLReturnValue, @"openURL: should have returned YES"); - KIFAssertEqual(YES, canOpenURLReturnValue, @"canOpenURL: should have returned YES"); - - [system waitForApplicationToOpenURLWithScheme:@"test123" whileExecutingBlock:^{ - NSURL *installedAppURL = [NSURL URLWithString:@"test123://some/path?query"]; - canOpenURLReturnValue = [[UIApplication sharedApplication] canOpenURL:installedAppURL]; - openURLReturnValue = [[UIApplication sharedApplication] openURL:installedAppURL]; - } returning:YES]; - KIFAssertEqual(YES, openURLReturnValue, @"openURL: should have returned YES"); - KIFAssertEqual(YES, canOpenURLReturnValue, @"canOpenURL: should have returned YES"); - - [system waitForApplicationToOpenAnyURLWhileExecutingBlock:^{ - NSURL *someURL = [NSURL URLWithString:@"423543523454://"]; - canOpenURLReturnValue = [[UIApplication sharedApplication] canOpenURL:someURL]; - openURLReturnValue = [[UIApplication sharedApplication] openURL:someURL]; - } returning:YES]; - KIFAssertEqual(YES, openURLReturnValue, @"openURL: should have returned YES"); - KIFAssertEqual(YES, canOpenURLReturnValue, @"canOpenURL: should have returned YES"); - - NSURL *fakeURL = [NSURL URLWithString:@"this-is-a-fake-url://"]; - KIFAssertFalse([[UIApplication sharedApplication] canOpenURL:fakeURL], @"Should no longer be mocking, reject bad URL."); - KIFAssertFalse([[UIApplication sharedApplication] openURL:fakeURL], @"Should no longer be mocking, reject bad URL."); -} - -#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 100000 -- (void)testMockingOpenURLiOS10xAndUp { __block BOOL canOpenURLReturnValue; [system waitForApplicationToOpenURL:@"test123://" whileExecutingBlock:^{ @@ -138,6 +96,5 @@ - (void)testMockingOpenURLiOS10xAndUp NSURL *fakeURL = [NSURL URLWithString:@"this-is-a-fake-url://"]; KIFAssertFalse([[UIApplication sharedApplication] canOpenURL:fakeURL], @"Should no longer be mocking, reject bad URL."); } -#endif @end diff --git a/Test Host/Base.lproj/MainStoryboard.storyboard b/Test Host/Base.lproj/MainStoryboard.storyboard index 1235360bd..59d0ffdd9 100644 --- a/Test Host/Base.lproj/MainStoryboard.storyboard +++ b/Test Host/Base.lproj/MainStoryboard.storyboard @@ -1,9 +1,9 @@ - + - + @@ -317,7 +317,7 @@ -