Keep It Functional - An iOS Functional Testing Framework

Related tags

Testing KIF
Overview

Build Status Carthage compatible CocoaPod Version

IMPORTANT! Even though KIF is used to test your UI, you need to add it to your Unit Test target, not your UI Test target. The magic of KIF is that it allows you to drive your UI from your unit tests and reap all the advantages of testing in-process.

KIF iOS Integration Testing Framework

KIF, which stands for Keep It Functional, is an iOS integration test framework. It allows for easy automation of iOS apps by leveraging the accessibility attributes that the OS makes available for those with visual disabilities.

KIF builds and performs the tests using a standard XCTest testing target. Testing is conducted synchronously in the main thread (running the run loop to force the passage of time) allowing for more complex logic and composition. This also allows KIF to take advantage of the Xcode Test Navigator, command line build tools, and Bot test reports.

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 or an earlier release.

Features

Minimizes Indirection

All of the tests for KIF are written in Objective-C. This allows for maximum integration with your code while minimizing the number of layers you have to build.

Easy Configuration

KIF integrates directly into your Xcode project, so there's no need to run an additional web server or install any additional packages.

Wide OS and Xcode coverage

KIF's test suite is being run against iOS 8+ and Xcode 7+. Lower versions will likely still work, but your mileage may vary. We do our best to retain backwards compatibility as much as possible.

Test Like a User

KIF attempts to imitate actual user input. Automation is done using tap events wherever possible.

Automatic Integration with Xcode Testing Tools

You can easily run a single KIF test with the Test Navigator or kick off nightly acceptance tests with Bots.

See KIF in Action

KIF uses techniques described below to validate its internal functionality. You can see a test suite that exercises its entire functionality by simply building and testing the KIF scheme with ⌘U. Look at the tests in the "KIF Tests" group for ideas on how to build your own tests.

Installation (with CocoaPods)

CocoaPods are the easiest way to get set up with KIF.

The first thing you will want to do is set up a test target you will be using for KIF. You may already have one named MyApplication_Tests if you selected to automatically create unit tests. If you did, you can keep using it if you aren't using it for unit tests. Otherwise, follow these directions to create a new one.

Select your project in Xcode and click on "Add Target" in the bottom left corner of the editor. Select iOS -> Test -> iOS Unit Testing Bundle. Give it a product name like "Acceptance Tests", "UI Tests", or something that indicates the intent of your testing process.

The testing target will add a header and implementation file, likely "Acceptance_Tests.m/h" to match your target name. Delete those.

Once your test target set up, add the following to your Podfile file. Use your target's name as appropriate.

target 'Your Apps' do
  ...
end

target 'Acceptance Tests' do
  pod 'KIF', :configurations => ['Debug']
end

After running pod install complete the tasks in Final Test Target Configurations below for the final details on getting your tests to run.

Installation (from GitHub)

To install KIF, you'll need to link the libKIF static library directly into your application. Download the source from the kif-framework/KIF and follow the instructions below. The screenshots are from Xcode 6 on Yosemite, but the instructions should be the same for Xcode 5 or later on any OS version.

We'll be using a simple project as an example, and you can find it in Documentation/Examples/Testable Swift in this repository.

Simple App

Add KIF to your project files

The first step is to add the KIF project into the ./Frameworks/KIF subdirectory of your existing app. If your project uses Git for version control, you can use submodules to make updating in the future easier:

cd /path/to/MyApplicationSource
mkdir Frameworks
git submodule add https://github.com/kif-framework/KIF.git Frameworks/KIF

If you're not using Git, simply download the source and copy it into the ./Frameworks/KIF directory.

Add KIF to Your Workspace

Let your project know about KIF by adding the KIF project into a workspace along with your main project. Find the KIF.xcodeproj file in Finder and drag it into the Project Navigator (⌘1).

Added KIF to the project

Create a Testing Target

You'll need to create a test target for your app. You may already have one named MyApplicationTests if you selected to automatically create unit tests when you created the project. If you did, you can keep using it if you aren't using it for unit tests. Otherwise, follow these directions to create a new one.

Select your project in Xcode and click on "Add Target" in the bottom left corner of the editor. Select iOS -> Test -> iOS Unit Testing Bundle. Give it a product name like "Acceptance Tests", "UI Tests", or something that indicates the intent of your testing process.

The testing target will add a header and implementation file, likely "Acceptance_Tests.m/h" to match your target name. Delete those.

Configure the Testing Target

Now that you have a target for your tests, add the tests to that target. With the project settings still selected in the Project Navigator, and the new integration tests target selected in the project settings, select the "Build Phases" tab. Under the "Link Binary With Libraries" section, hit the "+" button. In the sheet that appears, select "libKIF.a" and click "Add". Repeat the process for CoreGraphics.framework and QuartzCore.framework.

KIF requires the IOKit.framework, but it is not located with the other system frameworks. To link to it, add "-framework IOKit" to the "Other Linker Flags" build setting.

Add libKIF library screen shot

Add libKIF library screen shot

KIF takes advantage of Objective C's ability to add categories on an object, but this isn't enabled for static libraries by default. To enable this, add the -ObjC flag to the "Other Linker Flags" build setting on your test bundle target as shown below.

Add category linker flags screen shot

Read Final Test Target Configurations below for the final details on getting your tests to run.

Installing Accessibility Identifier Tests

Normally you identify a UI element via its accessibility label so that KIF simulates the interactions of a real user as closely as possible. In some cases, however, you may have to use accessibility identifiers, which are not exposed to users. If using CocoaPods, install the additional identifier-based KIF tests via the Identifier CocoaPods subspec:

pod 'KIF/IdentifierTests'

If not using CocoaPods, the identifier-based KIF tests can be added by including "KIFUITestActor-IdentifierTests.h".

Final Test Target Configurations

You need your tests to run hosted in your application. Xcode does this for you by default when creating a new testing bundle target, but if you're migrating an older bundle, follow the steps below.

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".

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".

Example test cases

With your project configured to use KIF, it's time to start writing tests. There are two main classes used in KIF testing: the test case (KIFTestCase, subclass of XCTestCase) and the UI test actor (KIFUITestActor). The XCTest test runner loads the test case classes and executes their test. Inside these tests, the tester performs the UI operations which generally imitate a user interaction. Three of the most common tester actions are "tap this view," "enter text into this view," and "wait for this view." These steps are included as factory methods on KIFUITestActor in the base KIF implementation.

KIF relies on the built-in accessibility of iOS to perform its test steps. As such, it's important that your app is fully accessible. This is also a great way to ensure that your app is usable by everyone. Giving your views reasonable labels is usually a good place to start when making your application accessible. More details are available in Apple's Documentation.

The first step is to create a test class to test some functionality. In our case, we will create a login test (LoginTests). Create a new class that inherits from KIFTestCase. You may have to update the import to point to <KIF/KIF.h>. The test method name provides a unique identifier. Your KIFTestCase subclass should look something like this:

LoginTestCase.h

#import <KIF/KIF.h>

@interface LoginTests : KIFTestCase
@end

LoginTestCase.m

#import "LoginTests.h"
#import "KIFUITestActor+EXAdditions.h"

@implementation LoginTests

- (void)beforeEach
{
    [tester navigateToLoginPage];
}

- (void)afterEach
{
    [tester returnToLoggedOutHomeScreen];
}

- (void)testSuccessfulLogin
{
    [tester enterText:@"[email protected]" intoViewWithAccessibilityLabel:@"Login User Name"];
    [tester enterText:@"thisismypassword" intoViewWithAccessibilityLabel:@"Login Password"];
    [tester tapViewWithAccessibilityLabel:@"Log In"];

    // Verify that the login succeeded
    [tester waitForTappableViewWithAccessibilityLabel:@"Welcome"];
}

@end

Most of the tester actions in the test are already defined by the KIF framework, but -navigateToLoginPage and -returnToLoggedOutHomeScreen are not. These are examples of custom actions which are specific to your application. Adding such steps is easy, and is done using a factory method in a category of KIFUITestActor, similar to how we added the scenario.

KIFUITestActor+EXAdditions.h

#import <KIF/KIF.h>

@interface KIFUITestActor (EXAdditions)

- (void)navigateToLoginPage;
- (void)returnToLoggedOutHomeScreen;

@end

KIFUITestActor+EXAdditions.m

#import "KIFUITestActor+EXAdditions.h"

@implementation KIFUITestActor (EXAdditions)

- (void)navigateToLoginPage
{
    [self tapViewWithAccessibilityLabel:@"Login/Sign Up"];
    [self tapViewWithAccessibilityLabel:@"Skip this ad"];
}

- (void)returnToLoggedOutHomeScreen
{
    [self tapViewWithAccessibilityLabel:@"Logout"];
    [self tapViewWithAccessibilityLabel:@"Logout"]; // Dismiss alert.
}

@end

Everything should now be configured. When you run the integration tests using the test button, ⌘U, or the Xcode Test Navigator (⌘5).

Use with other testing frameworks

KIFTestCase is not necessary for running KIF tests. Tests can run directly in XCTestCase or any subclass. The basic requirement is that when you call tester or system, self must be an instance of XCTestCase and you must call KIFEnableAccessibility in setUp.

For example, the following Specta test works without any changes to KIF or Specta:

#import <Specta.h>
#import <KIF.h>

SpecBegin(App)

describe(@"Tab controller", ^{

  it(@"should show second view when I tap on the second tab", ^{
    [tester tapViewWithAccessibilityLabel:@"Second" traits:UIAccessibilityTraitButton];
    [tester waitForViewWithAccessibilityLabel:@"Second View"];
  });

});

SpecEnd

If you want to use KIF with a test runner that does not subclass XCTestCase, your runner class just needs to implement the KIFTestActorDelegate protocol which contains two required methods.

  • (void)failWithException:(NSException *)exception stopTest:(BOOL)stop;
  • (void)failWithExceptions:(NSArray *)exceptions stopTest:(BOOL)stop;

In the first case, the test runner should log the exception and halt the test execution if stop is YES. In the second, the runner should log all the exceptions and halt the test execution if stop is YES. The exceptions take advantage of KIF's extensions to NSException that include the lineNumber and filename in the exception's userData to record the error's origin.

Use with Swift

Since it's easy to combine Swift and Objective-C code in a single project, KIF is fully capable of testing apps written in both Objective-C and Swift.

If you want to write your test cases in Swift, you'll need to keep two things in mind.

  1. Your test bundle's bridging header will need to #import <KIF/KIF.h>, since KIF is a static library and not a header.
  2. The tester and system keywords are C preprocessor macros which aren't available in Swift. You can easily write a small extension to XCTestCase or any other class to access them:
extension XCTestCase {
    func tester(file : String = #file, _ line : Int = #line) -> KIFUITestActor {
        return KIFUITestActor(inFile: file, atLine: line, delegate: self)
    }

    func system(file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
        return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
    }
}

extension KIFTestActor {
    func tester(file : String = #file, _ line : Int = #line) -> KIFUITestActor {
        return KIFUITestActor(inFile: file, atLine: line, delegate: self)
    }

    func system(file : String = #file, _ line : Int = #line) -> KIFSystemTestActor {
        return KIFSystemTestActor(inFile: file, atLine: line, delegate: self)
    }
}

See Documentation/Examples/Testable Swift for sample code.

Troubleshooting

Simulator launches but app doesn't appear, steps time out after 10 seconds

This issue occurs when XCTest does not have a valid test host. Reread the instructions above with regards to the "Bundle Loader" and "Test Host" settings. You may have missed something.

Step fails because a view cannot be found

If KIF is failing to find a view, the most likely cause is that the view doesn't have its accessibility label set. If the view is defined in a xib, then the label can be set using the inspector. If it's created programmatically, simply set the accessibilityLabel attribute to the desired label.

If the label is definitely set correctly, take a closer look at the error given by KIF. This error should tell you more specifically why the view was not accessible. If you are using -waitForTappableViewWithAccessibilityLabel:, then make sure the view is actually tappable. For items such as labels which cannot become the first responder, you may need to use -waitForViewWithAccessibilityLabel: instead.

Unrecognized selector when first trying to run

If the first time you try to run KIF you get the following error:

2011-06-13 13:54:53.295 Testable (Integration Tests)[12385:207] -[NSFileManager createUserDirectory:]: unrecognized selector sent to instance 0x4e02830
2011-06-13 13:54:53.298 Testable (Integration Tests)[12385:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSFileManager createUserDirectory:]: unrecognized selector sent to instance 0x4e02830'

or if you get another "unrecognized selector" error inside the KIF code, make sure that you've properly set the -ObjC flag as described above. Without this flag your app can't access the category methods that are necessary for KIF to work properly.

Continuous Integration

A continuous integration (CI) process is highly recommended and is extremely useful in ensuring that your application stays functional. The easiest way to do this will be with Xcode, either using Bots, or Jenkins or another tool that uses xcodebuild. For tools using xcodebuild, review the manpage for instructions on using test destinations.

Contributing

We're glad you're interested in KIF, and we'd love to see where you take it.

Any contributors to the master KIF repository must sign the Individual Contributor License Agreement (CLA). It's a short form that covers our bases and makes sure you're eligible to contribute.

When you have a change you'd like to see in the master repository, send a pull request. Before we merge your request, we'll make sure you're in the list of people who have signed a CLA.

Thanks, and happy testing!

Comments
  • Modify KIF to be XCTest and SenTestingKit compatible

    Modify KIF to be XCTest and SenTestingKit compatible

    Using preprocessor directives, I modified the files that were specifically referencing SenTestingKit to use XCTest if XCTest is imported otherwise default to keeping SenTestingKit. I created an additional static library, KIF-XCTest, that users can import into their projects if they want to use the XCTest version. Also, the podspec now uses subspecs so users can pick if they want to use the XCTest compatible version by specifying pod 'KIF/XCTest' or the SenTestingKit one, pod 'KIF'. The podspec defaults to the SenTestingKit version so people already using KIF won't have their tests broken.

    Questions Pending 
    opened by tonyd256 59
  • Fix for

    Fix for "Attempted to dequeue multiple cells for the same index path" in table views with Xcode 9

    Fixes #1007

    Trying out a fix for issue #1007. @justinseanmartin @RoyalPineapple please have a look?

    Thanks to Larry Gensch (non-github user at this time) who did all of the heavy lifting.

    Thanks, Mike

    opened by mikelupo 38
  • #1130 Initial swift package manager support

    #1130 Initial swift package manager support

    https://github.com/kif-framework/KIF/issues/1130

    As some project refers to openium/master and I don't want to force push to this branch, I created another branch to update my initial PR https://github.com/kif-framework/KIF/pull/1147 to current KIF master

    Basically the same changes (removing precompiled headers (.pch) and moving files to be "more" SPM compliant)

    opened by kenji21 36
  • No Autocomplete in Swift projects in XCode 7

    No Autocomplete in Swift projects in XCode 7

    At work we use KIF extensively and there are many Swift projects where autocomplete no longer works. This is not a session based behaviour, you can clone a new copy of the repo and autocomplete in KIF is nonexistent. All projects starts off with KIF autocomplete working but after a bit it stops. We have theorized it has something to do with the size of the project but no one seems to know for certain.

    Is this a known issue? Is there a fix for it?

    opened by abbeyjackson 31
  • Fixes issue with overreleased objects

    Fixes issue with overreleased objects

    The autoreleasepool causes overrelease issues with the out parameters (NSError ** and UIView **) Also I do not see any memory benefits using the autorelease pool here. (tested the footprint) Out parameters will be implicitly autoreleased. i.e. NSError *__autoreleasing * See more: http://blog.pioneeringsoftware.co.uk/2012/03/06/out-parameters-when-arcing/ It also fixes the issue we filed here https://github.com/kif-framework/KIF/issues/439

    opened by tapwork 28
  • NSInternalInconsistencyException scrolling UITableViews

    NSInternalInconsistencyException scrolling UITableViews

    Hi there - we're getting this error using the latest version of KIF on any waitForView(withAccessibilityLabel:) or tapView(withAccessibilityLabel:) that tries to interact with a UITableView:

    Attempted to dequeue multiple cells for the same index path, which is not allowed. If you really need to dequeue more cells than the table view is requesting, use the -dequeueReusableCellWithIdentifier: method (without an index path). Cell identifier: cell, index path: <NSIndexPath: 0x600000a360a0> {length = 2, path = 0 - 7}
    

    The offending code seems to be in UIView+KIFAdditions.m, line 254:

    UITableViewCell *cell = [tableView.dataSource tableView:tableView cellForRowAtIndexPath:indexPath];

    It's looking like to us that the issue is related to how that function looping through all the cells in a tableview to find its position, which either fails or takes a considerable amount of time, causing the operation to retry, or the tests to hang/fail. Commenting out this code (lines 252 - 273) allows the tests to progress naturally without interruption. Also, adding a significant amount of time padding (5-10s) for the view to load in with tester().wait(forTimeInterval:) before calling waitForView or tapView seems to help, though this adds significant time to testing.

    Even though the code is reused for collectionviews, it doesn't seem like

    Seems like this is only an issue with Xcode 9 and 8.3.3 is unaffected. Stack trace:

    caught "NSInternalInconsistencyException", "Attempted to dequeue multiple cells for the same index path, which is not allowed. If you really need to dequeue more cells than the table view is requesting, use the -dequeueReusableCellWithIdentifier: method (without an index path). Cell identifier: cell, index path: <NSIndexPath: 0x60c000a3e0e0> {length = 2, path = 0 - 7}"
    (
    	0   CoreFoundation                      0x000000011374f1cb __exceptionPreprocess + 171
    	1   libobjc.A.dylib                     0x00000001184adf41 objc_exception_throw + 48
    	2   CoreFoundation                      0x0000000113754362 +[NSException raise:format:arguments:] + 98
    	3   Foundation                          0x0000000117f52089 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 193
    	4   UIKit                               0x0000000115b737b4 -[UITableView _dequeueReusableCellWithIdentifier:forIndexPath:usingPresentationValues:] + 454
    	5   UIKit                               0x0000000115b735ba -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 89
    	6   UIKit                               0x000000013cfdc4b3 -[UITableViewAccessibility dequeueReusableCellWithIdentifier:forIndexPath:] + 285
    	7   DoordashConsumer                    0x000000011044b7c3 _T016DoordashConsumer19OrderListDatasourceC9tableViewSo07UITableG4CellCSo0hG0C_10Foundation9IndexPathV12cellForRowAttF + 1907
    	8   DoordashConsumer                    0x000000011044ba6c _T016DoordashConsumer19OrderListDatasourceC9tableViewSo07UITableG4CellCSo0hG0C_10Foundation9IndexPathV12cellForRowAttFTo + 92
    	9   KIF                                 0x0000000139d2f81e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 3822
    	10  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	11  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	12  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	13  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	14  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	15  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	16  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	17  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	18  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	19  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	20  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	21  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	22  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	23  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	24  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	25  KIF                                 0x0000000139d2ec8e -[UIView(KIFAdditions) accessibilityElementMatchingBlock:notHidden:] + 862
    	26  KIF                                 0x0000000139d2e8f8 -[UIView(KIFAdditions) accessibilityElementMatchingBlock:] + 72
    	27  KIF                                 0x0000000139d2e079 -[UIView(KIFAdditions) accessibilityElementWithLabel:accessibilityValue:traits:] + 249
    	28  KIF                                 0x0000000139d2731e -[UIApplication(KIFAdditions) accessibilityElementWithLabel:accessibilityValue:traits:] + 542
    	29  KIF                                 0x0000000139d24cb1 +[UIAccessibilityElement(KIFAdditions) accessibilityElementWithLabel:value:traits:fromRootView:error:] + 417
    	30  KIF                                 0x0000000139d24222 +[UIAccessibilityElement(KIFAdditions) accessibilityElement:view:withLabel:value:traits:fromRootView:tappable:error:] + 258
    	31  KIF                                 0x0000000139d240db +[UIAccessibilityElement(KIFAdditions) accessibilityElement:view:withLabel:value:traits:tappable:error:] + 235
    	32  KIF                                 0x0000000139d0e5b2 __83-[KIFUITestActor waitForAccessibilityElement:view:withLabel:value:traits:tappable:]_block_invoke + 114
    	33  KIF                                 0x0000000139d0a5b7 -[KIFTestActor tryRunningBlock:complete:timeout:error:] + 167
    	34  KIF                                 0x0000000139d0a8a9 -[KIFTestActor runBlock:complete:timeout:] + 137
    	35  KIF                                 0x0000000139d0a9b4 -[KIFTestActor runBlock:complete:] + 148
    	36  KIF                                 0x0000000139d0aa90 -[KIFTestActor runBlock:] + 64
    	37  KIF                                 0x0000000139d0e4db -[KIFUITestActor waitForAccessibilityElement:view:withLabel:value:traits:tappable:] + 331
    	38  KIF                                 0x0000000139d0e30e -[KIFUITestActor waitForViewWithAccessibilityLabel:value:traits:tappable:] + 206
    	39  KIF                                 0x0000000139d0df60 -[KIFUITestActor waitForViewWithAccessibilityLabel:traits:] + 96
    	40  DoordashConsumerFunctionalTests     0x0000000139caaa36 _T031DoordashConsumerFunctionalTests14A2CheckoutSpecC4specyyFyycfU_yycfU6_yycfU0_ + 214
    	41  Quick                               0x0000000139f59c96 _T05Quick7ExampleC3runyyF + 2198
    	42  Quick                               0x0000000139f5a8c4 _T05Quick7ExampleC3runyyFTo + 36
    	43  Quick                               0x0000000139f5139b __60+[QuickSpec addInstanceMethodForExample:classSelectorNames:]_block_invoke + 123
    	44  CoreFoundation                      0x00000001136d356c __invoking___ + 140
    	45  CoreFoundation                      0x00000001136d3440 -[NSInvocation invoke] + 320
    	46  XCTest                              0x00000001387a1949 __24-[XCTestCase invokeTest]_block_invoke + 591
    	47  XCTest                              0x00000001387e9f45 -[XCUITestContext performInScope:] + 183
    	48  XCTest                              0x00000001387a16ef -[XCTestCase invokeTest] + 141
    	49  XCTest                              0x00000001387a26b0 __26-[XCTestCase performTest:]_block_invoke.369 + 42
    	50  XCTest                              0x00000001387eec4b +[XCTContext runInContextForTestCase:block:] + 163
    	51  XCTest                              0x00000001387a204c -[XCTestCase performTest:] + 608
    	52  XCTest                              0x000000013879e052 __27-[XCTestSuite performTest:]_block_invoke + 363
    	53  XCTest                              0x000000013879d9b9 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 26
    	54  XCTest                              0x000000013879dbb6 -[XCTestSuite performTest:] + 239
    	55  XCTest                              0x000000013879e052 __27-[XCTestSuite performTest:]_block_invoke + 363
    	56  XCTest                              0x000000013879d9b9 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 26
    	57  XCTest                              0x000000013879dbb6 -[XCTestSuite performTest:] + 239
    	58  XCTest                              0x000000013879e052 __27-[XCTestSuite performTest:]_block_invoke + 363
    	59  XCTest                              0x000000013879d9b9 -[XCTestSuite _performProtectedSectionForTest:testSection:] + 26
    	60  XCTest                              0x000000013879dbb6 -[XCTestSuite performTest:] + 239
    	61  XCTest                              0x00000001387f616d __44-[XCTTestRunSession runTestsAndReturnError:]_block_invoke + 40
    	62  XCTest                              0x00000001387b1232 -[XCTestObservationCenter _observeTestExecutionForBlock:] + 475
    	63  XCTest                              0x00000001387f600c -[XCTTestRunSession runTestsAndReturnError:] + 281
    	64  XCTest                              0x000000013878d6ab -[XCTestDriver runTestsAndReturnError:] + 314
    	65  XCTest                              0x00000001387edeb6 _XCTestMain + 619
    	66  CoreFoundation                      0x00000001136f220c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
    	67  CoreFoundation                      0x00000001136d6a3b __CFRunLoopDoBlocks + 203
    	68  CoreFoundation                      0x00000001136d6214 __CFRunLoopRun + 1300
    	69  CoreFoundation                      0x00000001136d5a89 CFRunLoopRunSpecific + 409
    	70  GraphicsServices                    0x000000011d5f79c6 GSEventRunModal + 62
    	71  UIKit                               0x0000000115a35d30 UIApplicationMain + 159
    	72  DoordashConsumer                    0x000000010f615227 main + 55
    	73  libdyld.dylib                       0x0000000119ffcd81 start + 1
    	74  ???                                 0x0000000000000005 0x0 + 5
    
    opened by aeioliu 27
  • KIF/KIF.h file not found

    KIF/KIF.h file not found

    I am trying to integrate KIF into my AppleTV project. I'm using Xcode 7.2, programming in Swift and integrating KIF as download from GitHub. I followed all the steps in README, including the "Use with Swift" part, importing KIF in my bridging header and setting the path to this bridging header in Build Settings of my testing target. However when I try to run the tests with ⌘U (I did not really write any yet even, using the default implementation) I get the following two errors:

    • Tests-Bridging-Header.h -> 'KIF/KIF.h' file not found
    • Failed to import bridging header '/path/Tests-Bridging-Header.h'

    I assume that the second error will disappear once the first one is solved, but I do not know how to solve it. Any ideas?

    opened by janagrill 27
  • Make touch UIEvent compatible with iOS 8.3

    Make touch UIEvent compatible with iOS 8.3

    Tentative fix for https://github.com/kif-framework/KIF/issues/574

    Running KIF on iOS 8.3 (with XCode 6.3 Beta) leads to the following error screen shot 2015-03-01 at 10 51 33 pm

    Since it was referencing IOHIDEvent I looked into [UIEvent _hidEvent] private attribute and realized it was always nil for UIEvent created by KIF (unlike real UIEvents that have a valid _hidEvent). My guess was that starting with iOS 8.3, the usage of [UIEvent _gsEvent] was deprecated in favor on [UIEvent _hidEvent]. After some poking around, trial and error and the help of some code found on github I was able to fake this IOHIDEvent attribute. This solution relies heavily on iOS private APIs (IOKit private framework needs to be added) so I am not sure this is the best approach. @phatmann what do you think?

    I have tested on iOS 7.1, 8.1 and 8.3.

    opened by TBonnin 27
  • Add support for dismissing system alerts

    Add support for dismissing system alerts

    This is a first pass at dismissing system alerts (eg. location services and access to photos). It works by linking to the private UIAutomation framework and then calling down the UIAElement chain to grab the alert. It then taps the last button which should be the Allow one.

    Also of note is how the private headers are pulled in. In its current state all the knowledge lives in KIFSystemAlertHandler.m and only exposes the required methods. Take a peek at the full header dump and the inspiration for this if you are interested in seeing the full list. There is also the option of pulling one of those in as a Cocoapod and keeping all the knowledge contained there.

    This could be a solution for PR #507 running on CI but I want to first make sure this is an acceptable approach before continuing. If so, please let me know and I will continue with adding support for iOS 7.X and not failing the test if the alert never shows up.

    While this will not yet allow interaction with external views (eg. ABPeoplePickerNavigationController), it does mark a huge step forward for KIF being able to interact with elements outside of the standard accessibility hierarchy.

    opened by joemasilotti 27
  • Option to use accessabilityIdentifier instead of accessibilityLabel

    Option to use accessabilityIdentifier instead of accessibilityLabel

    Given that accessibilityLabel is an outwardly-facing string that is actually used by accessibility screen readers (and should be localized to the device user's language), Apple now provides an alternate property (iOS 5+) that is specifically intended for UI Automation purposes:

    @property(nonatomic, copy) NSString *accessibilityIdentifier;
    

    An identifier can be used to uniquely identify an element in the scripts you write using the UI Automation interfaces. Using an identifier allows you to avoid inappropriately setting or accessing an element’s accessibility label.

    Availability Available in iOS 5.0 and later.

    _Source:_ UIAccessibilityIdentification Protocol Reference

    Ideally, the KIF framework would give us an easy means to swap out the logic that looks for accessibilityLabel and instead use accessibilityIdentifier.

    opened by grgcombs 25
  • On Test Failure, an exception is thrown which doesn't get caught

    On Test Failure, an exception is thrown which doesn't get caught

    It appears to me KIF behaves quite strange when a test fails:

    I installed KIF via CocoaPods:

    target 'Acceptance Tests', :exclusive => true do
        pod 'KIF', '~> 3.0'
    end
    

    which built smoothly.

    My first attempt to use KIF is in this test:

    - (void)testOneRegulationShouldBeSelected
    {
        UITableView* tableView = (UITableView *)[tester waitForViewWithAccessibilityLabel:@"Regulation List"];
    
    //    [tester tapRowInTableViewWithAccessibilityLabel:@"Regulation List"
    //                                        atIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]];
    
        [tester waitForViewWithAccessibilityLabel:@"Checkmark" traits:UIAccessibilityTraitSelected];    
    }
    

    Since there was no row selected in the table view, the test should fail. I would expect a brief failure description printed to the console and some visual representation in Xcode's test navigator. That's not the case, though:

    Indeed, it fails after a timeout expired, but with throwing an exception which prints the call stack to the console:

    Acceptance Tests/StartupTests.m:37: error: -[StartupTests testOneRegulationShouldBeSelected] : The step timed out after 10.00 seconds: Failed to find accessibility element with the label "Checkmark" :0: error: -[StartupTests testOneRegulationShouldBeSelected] : The step timed out after 10.00 seconds: Failed to find accessibility element with the label "Checkmark" ( 0 CoreFoundation 0x019661e4 exceptionPreprocess + 180 1 libobjc.A.dylib 0x016e58e5 objc_exception_throw + 44 2 CoreFoundation 0x019f5fe1 -[NSException raise] + 17 3 Acceptance Tests 0x08bcc4ff -[XCTestCase(KIFAdditions) failWithException:stopTest:] + 479 4 Acceptance Tests 0x08bb32fa -[KIFTestCase failWithException:stopTest:] + 506 5 Acceptance Tests 0x08bb262b -[KIFTestActor failWithError:stopTest:] + 299 6 Acceptance Tests 0x08bb2046 -[KIFTestActor runBlock:complete:timeout:] + 758 7 Acceptance Tests 0x08bb21a2 -[KIFTestActor runBlock:complete:] + 194 8 Acceptance Tests 0x08bb22fc -[KIFTestActor runBlock:] + 108 9 Acceptance Tests 0x08bb5d16 -[KIFUITestActor waitForAccessibilityElement:view:withLabel:value:traits:tappable:] + 374 10 Acceptance Tests 0x08bb5b0d -[KIFUITestActor waitForViewWithAccessibilityLabel:value:traits:tappable:] + 253 11 Acceptance Tests 0x08bb5619 -[KIFUITestActor waitForViewWithAccessibilityLabel:traits:] + 137 12 Acceptance Tests 0x08bafe0d -[StartupTests testOneRegulationShouldBeSelected] + 685 13 CoreFoundation 0x0195a91d _invoking + 29 14 CoreFoundation 0x0195a82a -[NSInvocation invoke] + 362 15 XCTest 0x20103c6c -[XCTestCase invokeTest] + 221 16 XCTest 0x20103d7b -[XCTestCase performTest:] + 111 17 XCTest 0x20104c48 -[XCTest run] + 82 18 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139 19 XCTest 0x20104c48 -[XCTest run] + 82 20 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139 21 XCTest 0x20104c48 -[XCTest run] + 82 22 XCTest 0x201033e8 -[XCTestSuite performTest:] + 139 23 XCTest 0x20104c48 -[XCTest run] + 82 24 XCTest 0x201066ba +[XCTestProbe runTests:] + 183 25 Foundation 0x0131b5ec NSFireDelayedPerform + 372 26 CoreFoundation 0x01924ac6 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION + 22 27 CoreFoundation 0x019244ad __CFRunLoopDoTimer + 1181 28 CoreFoundation 0x0190c538 __CFRunLoopRun + 1816 29 CoreFoundation 0x0190b9d3 CFRunLoopRunSpecific + 467 30 CoreFoundation 0x0190b7eb CFRunLoopRunInMode + 123 31 GraphicsServices 0x039465ee GSEventRunModal + 192 32 GraphicsServices 0x0394642b GSEventRun + 104 33 UIKit 0x003a5f9b UIApplicationMain + 1225 34 Lexica 0x0001584d main + 157 35 libdyld.dylib 0x02102701 start + 1 )

    The XCTest case manages to proceed somehow, and logs this to the console:

    Test Case '-[StartupTests testOneRegulationShouldBeSelected]' failed (139.273 seconds). Test Suite 'StartupTests' finished at 2014-05-26 12:54:31 +0000. Executed 1 test, with 2 failures (2 unexpected) in 139.273 (139.323) seconds Test Suite 'Acceptance Tests.xctest' finished at 2014-05-26 12:54:31 +0000. Executed 1 test, with 2 failures (2 unexpected) in 139.273 (139.323) seconds Test Suite 'All tests' finished at 2014-05-26 12:54:31 +0000. Executed 1 test, with 2 failures (2 unexpected) in 139.273 (139.324) seconds

    Xcode's test navigator shows two failing tests:

    file:///Users/me/Projects/MyProject/Acceptance%20Tests/StartupTests.m: test failure: -[StartupTests testOneRegulationShouldBeSelected] failed: The step timed out after 10.00 seconds: Failed to find accessibility element with the label "Checkmark"

    and this one too:

    file:///%3Cunknown%3E: test failure: -[StartupTests testOneRegulationShouldBeSelected] failed: The step timed out after 10.00 seconds: Failed to find accessibility element with the label "Checkmark"

    Furthermore, while the test waits for the view to appear, a lot of memory gets allocated (several MBytes). I didn't investigate where this comes from, and whether this is a autorelease pool issue or a leak.

    I also get this strange error message in the console when KIF starts up:

    Cannot find executable for CFBundle 0xa86c520 </Applications/Xcode.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/AccessibilityBundles/CertUIFramework.axbundle> (not loaded)

    None of the suggested workarounds did actually work.

    It seems to me, I'm doing something fundamentally wrong ;)

    opened by couchdeveloper 24
  • Problems with async test

    Problems with async test

    Hi, I'm having problems when using an async test with KIF. I was able to create a simple app with one tests that always pass if the test is a sync function, but always fails if it is an async func:

    struct ContentView: View {
        
        @State var showAlert = false
        @State var showSheet = false
        
        var body: some View {
            NavigationView {
                VStack {
                    Button {
                        showAlert = true
                    } label: {
                        Text("Show alert")
                    }
                    .alert("Alert", isPresented: $showAlert) {
                        Button {
                            showSheet = true
                        } label: {
                            Text("Show sheet")
                        }
                    }
                    .sheet(isPresented: $showSheet) {
                        Text("Hello world")
                    }
                }
                .padding()
            }
        }
    }
    
    final class kifasyncTests: KIFTestCase {
        
        @MainActor
        func testAsyncMethod() async throws {
            // iOS 15.5 and 16.2 Always fails here. Nothing happens
            tester().tapView(withAccessibilityLabel: "Show alert")
            
            // iOS 15.4 Always fails here. I cannot see the alert button press
            tester().tapView(withAccessibilityLabel: "Show sheet")
            
            // iOS 16.0 Always fails here. I can see the alert button being press but the alert never dismiss
            try! tester().tryFindingView(withAccessibilityLabel: "Hello world")
        }
        
        //Always pass without any warning
        func testSyncMethod() {
            tester().tapView(withAccessibilityLabel: "Show alert")
            
            tester().tapView(withAccessibilityLabel: "Show sheet")
            
            try! tester().tryFindingView(withAccessibilityLabel: "Hello world")
        }
    }
    

    I'm able to reproduce the error with iOS 15.4, 15.5, 16.0 and 16.2 simulators (didn't test early versions) and with a real device with iOS 16.2. I'm using Xcode 14.2 and the latests KIF version from master.

    opened by BrunoMazzo 0
  • How to tap on system photo picker #help-wanted

    How to tap on system photo picker #help-wanted

    Any idea how to tap photo or at least cancel button on system photo picker? I've tried: [tester tapAccessibilityElement:] [tester tapScreenAtPoint:] [tester tapViewWithAccessibilityLabel:@"Cancel"]; [tester dismissPopover]

    None of these above do anything.

    (lldb) po [UIView printViewHierarchy]
    Window level 0.000000 (key window)
    ...
    |	UITransitionView
    |	|	UIDimmingView
    |	|	UIDropShadowView
    |	|	|	_UIRoundedRectShadowView (not highlighted)
    |	|	|	UIView
    |	|	|	|	UIView
    |	|	|	|	|	UILayoutContainerView
    |	|	|	|	|	|	UINavigationTransitionView
    |	|	|	|	|	|	|	UIViewControllerWrapperView
    |	|	|	|	|	|	|	|	_UISizeTrackingView
    |	|	|	|	|	|	|	|	|	_UIRemoteView, identifier: RemoteViewBridge
    |	|	|	|	|	|	|	|	|	AXRemoteElement, label: (null), traits: none
    |	|	|	|	|	|	UIToolbar, label: Toolbar, identifier: Toolbar (invisible)
    |	|	|	|	|	|	|	_UIBarBackground
    |	|	|	|	|	|	|	|	UIVisualEffectView
    |	|	|	|	|	|	|	|	|	_UIVisualEffectBackdropView
    |	|	|	|	|	|	|	|	_UIBarBackgroundShadowView
    |	|	|	|	|	|	|	|	|	_UIBarBackgroundShadowContentImageView (not highlighted)
    
    Window level 1.000000
    UITextEffectsWindow
    |	UIInputSetContainerView
    |	|	UIInputSetHostView
    |	_UITextEffectsRemoteView, identifier: RemoteViewBridge
    |	AXRemoteElement, label: (null), traits: none
    
    Simulator Screen Shot - iPhone SE (3rd generation)
    opened by lukaszkn 1
  • Tappable SwiftUI view that is not tapped by KIF

    Tappable SwiftUI view that is not tapped by KIF

    I have the following SwiftUI view that inserts a tappable row in a List:

    struct AddItemRow: View {
        let prompt: String
        let action: (() -> Void)?
        
        var body: some View {
            HStack {
                ZStack {
                    Image(systemName: "circle.fill")
                        .foregroundColor(.white)
                        .font(.system(.title2))
                        .padding(.leading, 0)
                    Image(systemName: "plus.circle.fill")
                        .foregroundColor(.green)
                        .font(.system(.title2))
                        .padding(.leading, 0)
                }
                .accessibilityHidden(true)
                
                Text(prompt)
                    .padding(.leading, 8.0)
                    .accessibilityRemoveTraits(.isStaticText)
                    .accessibilityIdentifier(prompt)
            }
            .frame(minHeight: 32.0)
            .onTapGesture(count: 1, perform: {
                action?()
            })
            .accessibilityAddTraits(.isButton)
            .accessibilityElement(children: .combine)
        }
    }
    

    I have KIF tests that previously worked with this view, before SwiftUI was adopted for this list, the main content of the screen, as a subview in a UIHostingController.

    My test calls the following support function:

    func addRow(_ type: ContactComponent) {
        let identifier = "add " + type.rawValue
        tester().waitForAnimationsToFinish()
        tester().tapView(withAccessibilityIdentifier: identifier) // brings row into view
        tester().waitForAnimationsToFinish()
        tester().tapView(withAccessibilityIdentifier: identifier)
        tester().waitForAnimationsToFinish()
    }
    

    Previously this worked correctly. Now, the row in question scrolls into view, but the second tap does not activate the row.

    Things I have tried:

    1. The row works fine in actual use.
    2. In Accessibility Inspector, the row is selectable, the label is the expected correct label, it has a button trait, and clicking "Activate" correctly activates the row.
    3. Altering the view so this row is already on screen when the view is first displayed does not make any difference. The row does not register a tap.
    4. Manually clicking the row in the iOS Simulator while the test is running correctly activates the action, which adds a row to the list, and the KIF test then successfully goes on to interact correctly with the textfields in that additional row.
    5. I have tried multiple ways to restructure the addItem view, such as setting .accessibilityElement(children: hidden) and then applying the accessibiltyLabel and accessibilityIdentifier to the whole view, or moving the order of the modifiers so the onTapGesture appears before or after the other view modifiers. This does not change anything. I am willing to try other combinations that might be suggested but it is likely I've already tried them. 😕

    Any leads would be appreciated. I am about to undertake a complete redesign of the rest of the app in SwiftUI. This is currently the only section in SwiftUI and the only place my KIF tests are failing. I would like to migrate forward my KIF tests if I can but I clearly need KIF to be able to tap SwiftUI elements that are user-tappable.

    opened by babbage 2
  • KIF causes exception on using WKWebView

    KIF causes exception on using WKWebView

    I add empty fullscreen empty WKWebView and try to click it but get exception: Thread 1: "[<WKWebView 0x7fcdf002f600> valueForUndefinedKey:]: this class is not key value coding-compliant for the key _internal." Sources: https://github.com/kif-framework/KIF/blob/master/Sources/KIF/Additions/UIView-KIFAdditions.m

    Let check:

    BOOL isWebView = [self isKindOfClass:[WKWebView class]]; //YES
    ...
    if ([NSStringFromClass([self class]) isEqual:@"UIWebBrowserView"]) { //NO
    } else if (isWebView) { //YES
      id webViewInternal = [self valueForKey:@"_internal"]; //Exception
      ...
    }
    

    What is @"_internal" for WKWebView?

    opened by gerchicovy 2
  • Xcode 14

    Xcode 14 "Failed to select from Picker"

    After upgrading to Xcode 14, UI tests that were using:

    tester.selectPickerViewRow(withTitle: "Title", inComponent: 0)

    are no longer working. I get the error message "Failed to select from Picker". When stepping through the KIF source code, the picker appears to be nil as if it can't find one on screen even though I see it when the tests are running.

    I'm wondering if this is a bug or if there is another way we should be selecting from a picker with Xcode 14.

    opened by iankoller-vivid 5
Releases(v3.8.7)
  • v3.8.7(Jun 3, 2022)

    Bug Fixes:

    • Fixes deployment target warning for SwiftPM
    • Fixes tappable point in SwiftUI
    • Fixes issue with NSPredicates in iOS 15.5

    Enhancements:

    • Adds identifier to view hierarchy printing
    Source code(tar.gz)
    Source code(zip)
  • v3.8.6(Dec 14, 2021)

    Bug Fixes:

    • Reverts CollectionView scrolling when finding an element that had unintended consequences
    • Scrolls to take actions on elements in a scrollview
    • Checks to see if a UIControl is enabled for isTappable
    Source code(tar.gz)
    Source code(zip)
  • v3.8.5(Nov 8, 2021)

    Bug Fixes:

    Bug in Xcode 13 where UITableViewCell cells are being reused and change when scrolling Mimics UITableView scrolling logic in UICollectionView

    Source code(tar.gz)
    Source code(zip)
  • v3.8.4(Nov 1, 2021)

    Bug Fixes:

    • Fixes bug in Xcode 13 where UITableViewCell labels are not being found in waitForView
    • Changes from using XCUI screenshot to manually snapshotting the main screen. In Xcode 13 it locks down XCUI so using the API crashes the application
    Source code(tar.gz)
    Source code(zip)
  • v3.8.3(Sep 9, 2021)

  • v3.8.2(Apr 3, 2021)

  • v3.8.1(Mar 1, 2021)

    Adds ability to configure first responder timeout

    • This may need to be be used for slower machines or machines that are more resource restricted
    Source code(tar.gz)
    Source code(zip)
  • v3.8.0(Feb 22, 2021)

    This release officially drops Xcode 10 support due to https://github.com/kif-framework/KIF/pull/1209

    • Re-adds snapshot images as XCTAttachments
    • Re-adds SwiftPM support
    • Fixes bug where typing doesn't wait for keyboard to finish typing before moving on with test
    Source code(tar.gz)
    Source code(zip)
  • v3.7.14(Jan 13, 2021)

  • v3.7.13(Dec 1, 2020)

    • Adds a Visualizer to the top of the highest window instead of it's own window to prevent issues from changing key windows.
    • Fixes date picker for iOS 14
    Source code(tar.gz)
    Source code(zip)
  • v3.7.12(Nov 5, 2020)

  • v3.7.11(Sep 10, 2020)

  • v3.7.10(Sep 9, 2020)

    • Now supports WKWebView

    Bug Fixes

    • Date picker debug formatting
    • FAltering CALayers when iterating by copying
    • Navigation back button tap for iOS 13+
    • Crash in _setIsFirstTouchInView and setIsTap for iOS 14
    • Xcode 12 compilation issue
    Source code(tar.gz)
    Source code(zip)
  • v3.7.9(Mar 31, 2020)

    Bug Fix:

    • Prevent EXC_BAD_ACCESS crash by null-checking proper error(@ericbomgardner #1116)
    • Fixed acknowledgeSystemAlert on iOS 13.1 (@ksuther #1126)
    • Fix bug when acknowledging system alerts in Xcode 11.1 (@briannewberry #1129)
    • Scroll once when waiting for UITableViewCells (@zradke #1141)

    Enhancement:

    • Widen firstResponder searches to all windows (@zradke #1143)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.8(Jun 18, 2019)

    Bug Fix:

    • Fix Xcode 11 (Beta) build error (implicit conversion warning) (@jneidlinger #1111)

    Enhancement:

    • Add atPosition: variations to UICollectionView waitForCellAtIndexPath methods (@gaperlinski @harleyjcooper #1109)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.7(May 6, 2019)

    Bug Fixes:

    • Fix issue with elements not becoming first responder fast enough (@justinseanmartin - #1100)
    • Fixing UICollectionView cell tapping (@harleyjcooper - #1106)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.6(Apr 17, 2019)

    Bug Fixes:

    • Don't crash if there is no key window (@justinseanmartin - #1099)
    • Remove check preventing scroll UITableViewCells (@justinseanmartin - #1102)
    • Fixing broken TableView scrolling (@harleyjcooper - #1103)

    Typo Fix:

    • Edit mistyping on KIFUITestActor.h (@cruisediary - #1101 )
    Source code(tar.gz)
    Source code(zip)
  • v3.7.5(Apr 1, 2019)

    Bug Fix:

    • Fix crash on rotate on very small angle (@Screon - #1080 & @justinseanmartin - #1081)
    • Avoid XCUIScreenshot in Xcode 10 Beta, where the functionality is broken (@justinseanmartin - #1087)
    • Fix scrollViewToVisible:animated: (@plu - #1094)
    • Fix warning of XCUIScreen availability (@kylejm - #1098)

    Enhancement:

    • Make XCTestCase 'just work' (@justinseanmartin - #1086)
      • No longer need to explicitly call KIFEnableAccessibility when not subclassing KIFTestCase
    Source code(tar.gz)
    Source code(zip)
  • v3.7.4(Jul 4, 2018)

    Bug Fix:

    • Adding stabilization code to waitForAnimationsToFinishWithTimeout (@harleyjcooper - #1060)
    • Fix for "Attempted to dequeue multiple cells for the same index path" XC9 crash (@mikelupo - #1020)

    Enhancement:

    • Add test failure screenshots as attachment to the Xcode test report (@maryamaffinityclick - #1073)

    Infrastructure:

    • Dropped Xcode 7 & iOS 8 from supported CI configurations, Xcode 10 coming soon (@mikelupo - #1076)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.3(Apr 19, 2018)

    Bug Fix:

    • Fixed an issue where the disabling of autocorrect/autopunctuation was only applying to UITextFields and not UITextViews (@harleyjcooper - 950ed40)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.2(Apr 11, 2018)

    Small release, generally related to scrolling correctness and minor opt-in performance improvement for tests that need to scroll a lot.

    Feature:

    • testActorAnimationsEnabled flag added to tester for disabling animations when KIF scrolls offscreen elements into the view (@pbartolome - e5448c5)

    Bug Fix:

    • Fix a build warning that would prevent consumption via Carthage (@hiltonc + @sassafrass - 5d3ed24)

    Infrastructure:

    • Added CI task that validates Carthage support (@justinseanmartin - 8cb63de)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.1(Mar 8, 2018)

    This was a minor KIF release to fix Carthage. Technically the CI config was added after the release of 3.7.1, but makes sense to lump it all in together.

    Bug Fix:

    • Fix a build warning that would prevent consumption via Carthage (Artur Rybak - 2453685)

    Infrastructure:

    • Add a CI configuration to ensure we don't regress Carthage support (@justinseanmartin - 8cb63de)
    Source code(tar.gz)
    Source code(zip)
  • v3.7.0(Mar 8, 2018)

    Thanks everyone that has contributed a patch to KIF since the 3.6.0 release!

    We're now validating support for Xcode 7 through 9 on Travis across iOS 8 through 11.

    Please start using the new and improved viewTester test actor as a replacement and report any issues. We believe the API is much more flexible in how it can be used. We are open to suggestions, but would highly encourage that new tests be written using the APIs exposed by the KIFUIViewTestActor.

    We aren't likely to actually deprecate the tester API anytime soon, however we have added the CFLAG DEPRECATE_KIF_TESTER. This can be used to prevent using the older API if you'd like to use that to enforce consistency across your codebase.

    Improvements:

    • Picker matching improvements containing custom labels (@deepakkumarsharma-tudip - 15094a1 5aed042)
    • Added usingAbsenceOfTraits: API (@zadr - 4c71c0e)
    • Added acknowledgeSystemAlertWithIndex API (@startupthekid - a21fca3)
    • Introduced KIFTextInputTraitsOverrides and suppress autocorrect & autopunctuation by default (@harleyjcooper - 313764c)

    Deprecations:

    • Introduced a new DEPRECATE_KIF_TESTER cflag to prevent direct usage of tester (@justinseanmartin - e103dd2)
    • Marked 'KIFUIViewTestActor clearTextFromFirstResponder' as deprecated, as it is redundant (@justinseanmartin - 3f753ed)
    • Dropped official support for Xcode 6, no more CI configuration (@justinseanmartin - 4f29fe0)
    • Some functionality is no longer testable on iOS 11, most notably the photo picker and activity sheet are no longer accessible via the app's view hierarchy (@justinseanmartin - d006865)

    Infrastructure:

    • Added Travis CI configurations and fixed tests to pass reliably on Xcode 8 & 9 (@justinseanmartin - ce27ff5 d006865 168c9e9)
    • Readme improvements around KIFEnableAccessibility requirement (@edwinlai - 759aff2)

    Bug fixes for Xcode 9 and iOS 11:

    • Decreased majorSwipeDisplacement for "swipe to delete" tableview style actions to make it work on iOS 11 (@0xpablo - 5c2ed35)
    • Use new tableViewCell private Accessibility API when attempting to find an element match (@banjun - 98e75d6)
    • Fixed build warnings for missing autoreleasing attributes (@StefanLage - e0676e1)
    • Fixed deactivateAppForDuration: to work on iOS 11 (@justinseanmartin - 4724aae)
    • Avoid programmatic scrolling to visible behavior when elements are already onscreen (@justinseanmartin - d006865)
    • Adjusted UITableView dragCell:toIndex:error: for behavior change in iOS 11 (@justinseanmartin - d006865)

    General bug fixes:

    • Safety check on enterText:expectedResult: when validateEnteredText == NO (@justinseanmartin - 57b47fc)
    • Check the correct error on writing screenshots (@webventil - b52c375)
    • Avoid system symbol collision with cstdlib (@voznesenskym - ff857fd)
    • Missing autoreleasepool in the clearTextFromFirstResponder action (James Smith - 07fef14)
    • Disable bitcode in the podspec (David Beck - f964e46)
    • Avoid common pitfall by asserting KIFEnableAccessibility call before starting tests (@justinseanmartin - c3080fc)
    Source code(tar.gz)
    Source code(zip)
  • v3.6.0(Aug 14, 2017)

    Added more functionality to the KIFUIViewTestActor to bring it to parity with functionality exposed via KIFUITestActor. I'm converting our call sites in our tests over to using viewTester, and these holes were identified in the process.

    Deprecated APIs:

    • [viewTester waitToBecomeTappable]
      • This is being replaced with [viewTester waitForTappableView], which returns the UIView that was matched.
    • [viewTester enterTextIntoCurrentFirstResponder:]
      • Please use [[viewTester usingFirstResponder] enterText] instead
    • [viewTester enterTextIntoCurrentFirstResponder:fallbackView:]
      • There isn't a clear use case about why the fallbackView parameter is needed. If you disagree, please open an issue with information about the use case.
    Source code(tar.gz)
    Source code(zip)
  • v3.5.2(May 1, 2017)

  • v3.5.1(Sep 8, 2016)

  • v3.5.0(Aug 11, 2016)

  • v3.4.2(Apr 8, 2016)

  • v3.4.1(Mar 8, 2016)

  • v3.4.0(Mar 7, 2016)

    This release introduces the KIFUIViewTestActor class, courtesy of @RoyalPineapple, which separates the APIs of finding an element from acting on an element. This reduces the number of methods needed dramatically, and will become the default test actor in KIF 4.0. Please see the pull request #794 for more info.

    Travis is finally reliable again, thanks to @justinseanmartin.

    In addition there are misc bug fixes and additions, thanks to the tireless work of all of our contributors.

    Source code(tar.gz)
    Source code(zip)
Owner
KIF Framework
KIF Framework
Switchboard - easy and super light weight A/B testing for your mobile iPhone or android app. This mobile A/B testing framework allows you with minimal servers to run large amounts of mobile users.

Switchboard - easy A/B testing for your mobile app What it does Switchboard is a simple way to remote control your mobile application even after you'v

Keepsafe 287 Nov 19, 2022
SwiftCheck is a testing library that automatically generates random data for testing of program properties

SwiftCheck QuickCheck for Swift. For those already familiar with the Haskell library, check out the source. For everybody else, see the Tutorial Playg

TypeLift 1.4k Dec 21, 2022
Testing the UI without UI Testing, a Swift experiment.

UI tests without UI Testing experiment This repo is a small experiment to see if there's an "in-between" for testing iOS applications. More feature-le

Joe Masilotti 20 Sep 26, 2022
Remote configuration and A/B Testing framework for iOS

MSActiveConfig v1.0.1 Remote configuration and A/B Testing framework for iOS. Documentation available online. MSActiveConfig at a glance One of the bi

Elevate 78 Jan 13, 2021
AB testing framework for iOS

ABKit Split Testing for Swift. ABKit is a library for implementing a simple Split Test that: Doesn't require an HTTP client written in Pure Swift Inst

Recruit Marketing Partners Co.,Ltd 113 Nov 11, 2022
The Swift (and Objective-C) testing framework.

Quick is a behavior-driven development framework for Swift and Objective-C. Inspired by RSpec, Specta, and Ginkgo. // Swift import Quick import Nimbl

Quick 9.6k Dec 31, 2022
Genything is a framework for random testing of a program properties.

Genything is a framework for random testing of a program properties. It provides way to random data based on simple and complex types.

Just Eat Takeaway.com 25 Jun 13, 2022
T - A simple testing framework using closures and errors

t Quickly test expectations What is t? t is a simple testing framework using clo

OpenBytes 6 Nov 7, 2022
Snapshot testing tool for iOS and tvOS

SnapshotTest is a simple view testing tool written completely in Swift to aid with development for Apple platforms. It's like unit testing for views.

Pär Strindevall 44 Sep 29, 2022
Implementing and testing In-App Purchases with StoreKit2 in Xcode 13, Swift 5.5 and iOS 15.

StoreHelper Demo Implementing and testing In-App Purchases with StoreKit2 in Xcode 13, Swift 5.5, iOS 15. See also In-App Purchases with Xcode 12 and

Russell Archer 192 Dec 17, 2022
A Mac and iOS Playgrounds Unit Testing library based on Nimble.

Spry Spry is a Swift Playgrounds Unit Testing library based on Nimble. The best thing about Spry is that the API matches Nimble perfectly. Which means

Quick 327 Jul 24, 2022
Multivariate & A/B Testing for iOS and Mac

This library is no longer being maintained. You can continue to use SkyLab in your projects, but we recommend switching another solution whenever you

Mattt 792 Dec 15, 2022
An understated approach to iOS integration testing.

Subliminal is a framework for writing iOS integration tests. Subliminal provides a familiar OCUnit/XCTest-like interface to Apple's UIAutomation frame

Inkling 762 Nov 8, 2022
Bluepill is a reliable iOS testing tool that runs UI tests using multiple simulators on a single machine

Bluepill is a tool to run iOS tests in parallel using multiple simulators. Motivation LinkedIn created Bluepill to run its large iOS test suite in a r

Mobile Native Foundation 3.1k Jan 3, 2023
iOS Simulator type agnostic snapshot testing, built on top of the FBSnapshotTestCase.

SnappyTestCase iOS Simulator type agnostic snapshot testing, built on top of the FBSnapshotTestCase. Why? Snapshot testing helps to deliver views that

Tooploox 15 Oct 11, 2019
Sample project for testing out focus in SwiftUI and iOS 15

This project was to test out different ways of enabling focus in a SwiftUI app.

null 3 Dec 21, 2021
A flexible mock server for automated and regression testing of iOS, Android and other apps.

Note: This document is intended as a quick introduction to Voodoo. As Voodoo has a large number of features, please refer to Voodoo's Github Wiki for

Derek Clarkson 7 Nov 23, 2022
Network testing for Swift

DVR DVR is a simple Swift framework for making fake NSURLSession requests for iOS, watchOS, and OS X based on VCR. Easy dependency injection is the ma

Venmo 650 Nov 3, 2022
UI Testing Cheat Sheet and Examples.

UI Testing Cheat Sheet This repository is complementary code for my post, UI Testing Cheat Sheet and Examples. The post goes into more detail with exa

Joe Masilotti 2.1k Dec 25, 2022