Skip to content
iOS Automator
Swift Ruby Objective-C
Branch: master
Clone or download
kviksilver Merge pull request #115 from ianfixes/V2-rebase
V2 (Swift rewrite) rebased off master
Latest commit c689245 May 7, 2018
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
Docs Add project file for Carthage support and update CI May 7, 2018
Example Add project file for Carthage support and update CI May 7, 2018
Illuminator Add project file for Carthage support and update CI May 7, 2018
Pod
.gitignore ignore ruby bundle May 7, 2018
.gitmodules
.swift-version Add project file for Carthage support and update CI May 7, 2018
.travis.yml avoid ruby 2.4 which conflicts with json gem May 7, 2018
Gemfile [example] attempt to make all tests pass May 7, 2018
Gemfile.lock
Illuminator.podspec
IlluminatorBridge.podspec
LICENSE.txt Fix license and README May 7, 2018
README.md

README.md

Illuminator

CI Status Version License Platform

Illuminator makes your UI tests readable, reusable, and repairable

Readability

Where XCUITest generates a sequence of low-level element interactions, Illuminator tests are expressed as sequences of aptly-named (according to you, the developer) actions. A detailed picture of what the test accomplishes should be apparent from the action names alone.

    func testWithIlluminator() {

        initialState
            .apply(wf.welcome.continueAsGuest())
            .apply(wf.pushNotificationPermissions.decline())
            .apply(wf.home.searchFor("table"))
            .apply(wf.browse.verifySubcategory("End tables", expected: true))
            .apply(wf.browse.verifySubcategory("Bobby tables", expected: false))
            .apply(wf.browse.openSubcategory("Coffee tables"))
            .apply(wf.browse.openProduct(atIndex: 3))
            .apply(wf.productPage.addToCart(quantity: 2))
            .apply(wf.welcomePopup.signIn())
            .apply(wf.signInModal.submitCredentials(testAccount, password: testAccountPassword))
            .apply(wf.cart.verifyTotalItems(2))
            .apply(wf.cart.submitOrder())
            .apply(wf.orderConfirmation.verifyIsActive())
            .finish(self)
    }

Reusability

Your tests don't need to explicitly check whether they're on the right screen before every UI element interaction; Illuminator does it for you. Illuminator provides a system for grouping actions into the "screens" where they are available, and centralizes the logic for indicating when that screen is visible.

In the example above, welcome, pushNotificationPermissions, home, browse, productPage, welcomePopup, signInModal, cart, and orderConfirmation are the screens.

A sample app definition would include the following code:

public typealias AppTestState = [String: String]

public struct WayfairTestApp: IlluminatorApplication {

    var welcome: WelcomeScreen {
        get {
            return WelcomeScreen(testCaseWrapper: testCaseWrapper)
        }
    }

    /// snip

And the definition of the welcome screen would include:

public class WelcomeScreen: IlluminatorDelayedScreen<AppTestState> {
        
    public override var isActive: Bool {
        return app.navigationBars["Welcome"].exists
    }

     public func continueAsGuest() -> IlluminatorActionGeneric<AppTestState> {
        return makeAction() {
            try self.app.buttons["Continue as Guest"].ready().tap()
        }
    }

    /// snip

Repairability

Failing XCTestcase test functions indicate the file and line of the failure. That's not good enough. Illuminator tests can indicate the file and line of the failure as well as a detailed description of the app state at the time of the failure. For example, here is a sample of copy-pastable swift code generated by Illuminator between a test failure and the actual XCFail() call:

app.tabBars.elementBoundByIndex(0).buttons["Home"]
app.tabBars.elementBoundByIndex(0).buttons["Sales"]
app.tabBars.elementBoundByIndex(0).buttons["My Boards"]
app.tabBars.elementBoundByIndex(0).buttons["Account"]
app.tabBars.elementBoundByIndex(0).buttons["Cart"]
app.navigationBars["Welcome"]
app.navigationBars["Welcome"].buttons["close"]
app.navigationBars["Welcome"].staticTexts["Welcome"]
app.images["UniformCanvasLogo-Wayfair_US.jpg"]
app.staticTexts["Please Register or Sign In with your Wayfair.com account."]
app.buttons["Register"]
app.buttons["Sign In"]
app.staticTexts["or"]

Of course, this is ordinarily impossible. Illuminator accomplishes this by meticulously working around XCUIElement operations that trigger immediate test failures (like XCUIElementQuery operations that return multiple elements or XCUIElement operations on nonexistent elements). In the previous example, this was accomplished by Illuminator's .ready() function, which throws a catchable exception rather than trigger a test failure.

Bottom line? In many cases you can repair broken CI tests without re-running the failing test in your IDE; just find the relevant element reference in the console output and copy/paste it into your screen or action as appropriate.

Documentation

See Docs/.

Usage

To run the example project, clone the repo, and run pod install from the Example directory first.

Installation

Illuminator is available through CocoaPods. To install it, simply add the following line to your Podfile:

pod "Illuminator"

Authors

License

Illuminator is available under the Apache 2.0 license. See the LICENSE.txt file for more info.

You can’t perform that action at this time.