Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 504
drshock Avatar asked May 28 '17 01:05

drshock


3 Answers

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)

like image 89
AKM Avatar answered Nov 15 '22 21:11

AKM


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.

like image 36
drshock Avatar answered Nov 15 '22 20:11

drshock


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")
like image 23
Martin Bailey Avatar answered Nov 15 '22 19:11

Martin Bailey