How to tell which device I'm on in Xcode UI Testing?
Asked Answered
B

6

25

While an Xcode UI Test is running, I want to know which device/environment is being used (e.g. iPad Air 2, iOS 9.0, Simulator).

How can I get this information?

Basidiomycete answered 30/8, 2015 at 16:16 Comment(0)
V
30

Using Swift 3 (change .pad to .phone as necessary):

if UIDevice.current.userInterfaceIdiom == .pad {
    // Ipad specific checks
}

Using older versions of Swift:

UIDevice.currentDevice().userInterfaceIdiom
Valente answered 26/10, 2015 at 22:18 Comment(0)
C
11

Unfortunately there is no direct way of querying the current device. However you can work around by querying the size classes of the device:

private func isIpad(app: XCUIApplication) -> Bool {
    return app.windows.elementBoundByIndex(0).horizontalSizeClass == .Regular && app.windows.elementBoundByIndex(0).verticalSizeClass == .Regular
}

As you can see in the Apple Description of size classes, only iPad devices (currently) have both vertical and horizontal size class "Regular".

Coriss answered 8/6, 2016 at 8:3 Comment(1)
"Unfortunately there is no direct way of querying the current device" is a bit misleading - you cannot get the full device details but you can distinguish iPads and iPhones, see cakes88's answer using UIDevice.current.userInterfaceIdiom.Sendoff
B
5

You can check using the windows element frame XCUIApplication().windows.element(boundBy: 0).frame and check the device type.

You can also set an extension for XCUIDevice with a currentDevice property:

/// Device types
public enum Devices: CGFloat {

    /// iPhone
    case iPhone4 = 480
    case iPhone5 = 568
    case iPhone7 = 667
    case iPhone7Plus = 736

    /// iPad - Portraite
    case iPad = 1024
    case iPadPro = 1366

    /// iPad - Landscape
    case iPad_Landscape = 768
    case iPadPro_Landscape = 0
}

/// Check current device
extension XCUIDevice {
    public static var currentDevice:Devices {
        get {
            let orientation = XCUIDevice.shared().orientation

            let frame = XCUIApplication().windows.element(boundBy: 0).frame

            switch orientation {
            case .landscapeLeft, .landscapeRight:
                return frame.width == 1024 ? .iPadPro_Landscape : Devices(rawValue: frame.width)!
            default:
                return Devices(rawValue: frame.height)!
            }
        }
    }
}

Usage

let currentDevice = XCUIDevice.currentDevice

Brave answered 12/5, 2017 at 6:54 Comment(1)
Not sure why this is getting down voted . The XCUIApplication().windows.element(boundBy: 0).frame was the line I really needed to be able to tell difference devices apart. Thanks!Archenemy
B
2

Maybe someone would be come in handy the same for XCTest on Objective C:

// Check if the device is iPhone
if ( ([[app windows] elementBoundByIndex:0].horizontalSizeClass != XCUIUserInterfaceSizeClassRegular) || ([[app windows] elementBoundByIndex:0].verticalSizeClass != XCUIUserInterfaceSizeClassRegular) ) {
    // do something for iPhone
}
else {
    // do something for iPad
}
Briones answered 14/12, 2016 at 15:50 Comment(0)
B
0
  • Swift: 5.2.4
  • Xcode: 11.6
var isiPad: Bool {
   return UIDevice.current.userInterfaceIdiom == .pad
}

Breunig answered 1/8, 2020 at 21:9 Comment(0)
B
0

With iOS13+, you can now use UITraitCollection.current to get the complete set of traits for the current environment. (This is the "iOS interface environment for your app, including traits such as horizontal and vertical size class, display scale, and user interface idiom." doc)

In your case, you can access its property .userInterfaceIdiom to check for one of the device types in the UIUserInterfaceIdiom enumeration.

As an aside, if you just want to get the horizontal/vertical size classes of the trait collection, you can be more backwards compatible with your tests (Xcode 10.0+) just by accessing myXCUIElement.horizontalSizeClass and .verticalSizeClass within your test, as they are exposed via the XCUIElementAttributes protocol that all UI elements adopt. (Note though that I was getting .unspecified when calling off of XCUIApplication(); best to use a real UI element in a window. If you don't have one on hand, you can always still use something like app!.windows.element(boundBy: 0).horizontalSizeClass == .regular as mentioned in the past.)

Breccia answered 9/6, 2021 at 10:49 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.