How to disable auto-complete when running Xcode UI Tests?
Asked Answered
V

3

7

As part of my UI Tests, I'm generating a random string as titles for my objects. The problem is that when this title is input via a keyboard (using XCUIElement.typeText()), iOS sometimes accepts an auto-suggested value instead.

For example, I may want it to type an auto generated string of "calg", but auto correct will choose "calf" instead. When I try to look for this value later on with an assertion, it doesn't exist and fails incorrectly.

Is there a way to tell the UI tests that they shouldn't be using auto correct, or are there an workarounds I can use?

Vengeance answered 1/10, 2015 at 23:30 Comment(0)
N
5

Unless you need auto-suggest for any test scenarios, did you try turning off auto-correction in device/simulator settings.

Settings-> General -> Keyboard -> Auto-Correction

Newsmagazine answered 2/10, 2015 at 2:46 Comment(2)
This is nice for local test run. However, it doesn't work for CI.Autoharp
I just tried to find a workaround for this myself but couldn't find any clean one. I think the reasonable solution is that all CI providers should configure their simulators with autocorrection turned off by default for the short term, so feel free to contact them, I'm sure they'll help you. It's on Apple though to provide a solution (e.g. an option in Xcode within the scheme) for this long term, so you might want to post a feature request via the bug reporter. The more people do, the more likely it'll be implemented.Chavaree
J
5

I don't believe you can turn off auto-correction through code from your UI Testing target.

You can, however, turn it off for the individual text view from your production code. To make sure auto-correction is still on when running and shipping the app, one solution would be to subclass UITextField and switch on an environment variable.

First set up your UI Test to set the launchEnvironment property on XCUIApplication.

class UITests: XCTestCase {
    let app = XCUIApplication()

    override func setUp() {
        super.setUp()
        continueAfterFailure = false
        app.launchEnvironment = ["AutoCorrection": "Disabled"]
        app.launch()
    }

    func testAutoCorrection() {
        app.textFields.element.tap()
        // type your text
    }
}

Then subclass (and use) UITextField to look for this value in the process's environment dictionary. If it's set, turn auto-correction off. If not, just call through to super.

class TestableTextField: UITextField {
    override var autocorrectionType: UITextAutocorrectionType {
        get {
            if NSProcessInfo.processInfo().environment["AutoCorrection"] == "Disabled" {
                return UITextAutocorrectionType.No
            } else {
                return super.autocorrectionType
            }
        }
        set {
            super.autocorrectionType = newValue
        }
    }
}
Jackjackadandy answered 2/10, 2015 at 10:37 Comment(3)
It's interesting idea. However, the downside obviously that you have subclass ALL text fields in the application. It can make sense to swizzle UITextField class methods to implement it.Autoharp
Here are some pointers regarding swizzling it: #9670821Autoharp
thats the perfect answer i think.Piranha
W
0

Here is how I disabled it in my UI Test

    app.textFields.element(boundBy: 0).tap()

    let keyboards = app.keyboards.count
    XCTAssert(keyboards > 0, "You need enable the keyboard in the simulator.")

    app.buttons["Next keyboard"].press(forDuration: 2.1)

    let predictiveOn = app.switches["Predictive"].value as! String == "1"

    if predictiveOn {
        app.switches["Predictive"].tap()
    } else {
        app.buttons["Next keyboard"].tap()
    }

    app.buttons["Next keyboard"].press(forDuration: 2.1)

    let predictiveOff = app.switches["Predictive"].value as! String == "0"
    XCTAssert(predictiveOff, "Predictive mode is not disabled")

    app.buttons["Next keyboard"].tap()
Worldshaking answered 27/8, 2017 at 3:56 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.