From an XCUITest how can I check the on/off state of a UISwitch?
Asked Answered
A

5

14

I recently ran into a situation where I needed to be able to check the current on/off state (NOT whether it is enabled for user interaction) of a UISwitch from within an existing bucket of XCUITests, not an XCTest, and toggle it to a pre-determined state. I had added app state restoration to an old existing app and this is now interfering with a number of existing testcases between runs that expected the UISwitches in particular default states.

Unlike XCTest, within XCUITest you do not have access to the UISwitch state directly.

How is this state determined in Objective-C for an XCUITest?

Ampere answered 28/5, 2017 at 1:19 Comment(0)
A
16

Failing to find this anywhere obvious I happened upon this blog post for a similar situation for the Swift language. Xcode UITests: How to check if a UISwitch is on

With this information I tested and verified two approaches to solve my problem.

1) To assert if the state is on or off

XCUIElement *mySwitch = app.switches[@"My Switch Storyboard Accessibility Label"];
// cast .value to (NSString *) and test for @"0" if off state 
XCTAssertEqualObjects((NSString *)mySwitch.value, @"0", @"Switch should be off by default.");  // use @"1" to test for on state

2) To test if the state of the switch is on or off then toggle its state

XCUIElement *mySwitch = app.switches[@"My Switch Storyboard Accessibility Label"];
// cast .value to (NSString *) and test for @"0" if off state 
if (![(NSString *)mySwitch.value isEqualToString:@"0"])
        [mySwitch tap];  // tap if off if it is on

Using approach (2), I was able to force a default state for all UISwitches in between testcase runs and avoid the state restoration interference.

Ampere answered 28/5, 2017 at 1:19 Comment(2)
@JohnAlexanderBetts I'm not using any third party library. This is all out of the box Xcode stuff.Ampere
For a long time I was trying to access the switch via app.buttons but it was actually app.switches.Allover
K
14

Swift 5 version:

XCTAssert((activationSwitch.value as? String) == "1")

Alternatively you can have a XCUIElement extension

import XCTest

extension XCUIElement {
    var isOn: Bool? {
        return (self.value as? String).map { $0 == "1" }
    }
}

// ...

XCTAssert(activationSwitch.isOn == true)

Kopeck answered 6/12, 2019 at 9:46 Comment(1)
Do you know how to do this for ios 12? From what I've been seeing on my simulators, switch elements always seem to have value of nil. I haven't found a workaround yet, see forums.developer.apple.com/thread/124763Jeannajeanne
I
3

Define

extension XCUIElement {
    var isOn: Bool {
        (value as? String) == "1"
    }
}

Then

XCAssertTrue(someSwitch.isOn)
Isidoro answered 9/3, 2021 at 11:4 Comment(0)
F
1

Swift 5: Not sure if this will be of use to anyone, but I've just started using XCTest, and based on @drshock's reply to this question I created a simple function that I added to my XCTestCase that turns a switch only when it's off.

    let app = XCUIApplication()

    func turnSwitchOnIfOff(id: String) {

        let myControl : NSString = app.switches.element(matching: .switch, identifier: id).value as! NSString

        if myControl == "0" {

            app.switches.element(matching: .switch, identifier: id).tap()

        }

    }

Then in my test when I want to turn a switch on if it's off I use this, where the id is the Identifier string from the switches Accessibility section.

    turnSwitchOnIfOff(id: "accessibilityIdentifierString")
Fuchs answered 5/1, 2021 at 7:34 Comment(0)
S
0

For Swift

Add an extension to XCUIElement assert directly switch isOn status.

extension XCUIElement {
    
    func assert(isOn: Bool) {
        guard let intValue = value as? String else {
            return XCTAssert(false, "The value of element could not cast to String")
        }
        
        XCTAssertEqual(intValue, isOn ? "1" : "0")
    }
}

Usage

yourSwitch.assert(isOn: true)
Simmon answered 30/7, 2020 at 8:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.