Dunfey · Hotel WWDC as data, est. 1983
Front desk everything
Years
Topics

2021 Developer Tools

WWDC21 · 9 min · Developer Tools

Explore Digital Crown, Trackpad, and iPad pointer automation

Learn how you can interact with devices in UI Tests in Xcode 13. Discover newly-automatable input methods including iPadOS pointer, watchOS Digital Crown, and enhanced macOS trackpad scrolling APIs.

Watch at developer.apple.com ↗

Transcript all transcripts

Code shown on screen · 9 snippets

New supportsPointerInteraction property on XCUIDevice swift · at 1:28 ↗
extension XCUIDevice {

  public var supportsPointerInteraction: Bool

}
New methods on XCUIElement and XCUICoordinate for pointer interactions on iOS swift · at 1:37 ↗
extension XCUIElement {
  open func hover()

  open func click()

  open func rightClick()

  open func doubleClick()

  open func scroll(byDeltaX: CGFloat, deltaY: CGFloat)

  open func click(forDuration: TimeInterval, thenDragToElement: XCUIElement)

  open func click(forDuration: TimeInterval, thenDragToElement: XCUIElement,
                  withVelocity: XCUIGestureVelocity, thenHoldForDuration: TimeInterval)

  open class func perform(withKeyModifiers flags: XCUIElement.KeyModifiers,
                          block: () -> Void)
}
Empty UI test class swift · at 2:31 ↗
import XCTest

class Pointer_UI_Tests: XCTestCase {



}
UI test for opening the sidebar with a two-finger horizontal trackpad swipe swift · at 2:43 ↗
import XCTest

class Pointer_UI_Tests: XCTestCase {

  @available(iOS 15.0, *)
  func testHorizontalScrollRevealsSidebar() throws {
    let app = XCUIApplication()
    app.launch()

    let sidebar = app.tables["Sidebar"]

    // Make sure sidebar menu is not present initially.
    XCTAssertFalse(sidebar.exists, "Sidebar should not be present initially")

    // Swipe horizontally to reveal sidebar.
    app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0)

    // Verify sidebar is now present.
    XCTAssertTrue(sidebar.waitForExistence(timeout: 5),
                  "Sidebar did not appear within 5 second timeout")
  }

}
Use the new supportsPointerInteraction property to skip the test on devices that don't support pointer interaction swift · at 4:36 ↗
import XCTest

class Pointer_UI_Tests: XCTestCase {

  @available(iOS 15.0, *)
  func testHorizontalScrollRevealsSidebar() throws {
    try XCTSkipUnless(XCUIDevice.shared.supportsPointerInteraction,
                      "Device does not support pointer interaction")

    let app = XCUIApplication()
    app.launch()

    let sidebar = app.tables["Sidebar"]

    // Make sure sidebar menu is not present initially.
    XCTAssertFalse(sidebar.exists, "Sidebar should not be present initially")

    // Swipe horizontally to reveal sidebar.
    app.staticTexts["Select a smoothie"].scroll(byDeltaX: -200, deltaY: 0)

    // Verify sidebar is now present.
    XCTAssertTrue(sidebar.waitForExistence(timeout: 5),
                  "Sidebar did not appear within 5 second timeout")
  }

}
New method on XCUIDevice for Digital Crown rotation on watchOS swift · at 5:27 ↗
// New rotateDigitalCrown API

extension XCUIDevice {

  open func rotateDigitalCrown(delta: CGFloat, velocity: XCUIGestureVelocity = .default)

}
UI test to verify the app's Digital Crown rotation functionality behaves as expected swift · at 6:22 ↗
// Example use of watchOS Digital Crown API

func testForecastScrolling() {
  let app = XCUIApplication()
  app.launch()

  let forecastTime = app.staticTexts["forecast-time"]

  XCTAssertEqual(forecastTime.label, "Current Temperature")

  // Scroll 1 full rotation forward.
  XCUIDevice.shared.rotateDigitalCrown(delta: 1.0)
  XCTAssertEqual(forecastTime.label, "One hour from now")

  // Scroll 2 full rotations backward.
  XCUIDevice.shared.rotateDigitalCrown(delta: -2.0)
  XCTAssertEqual(forecastTime.label, "One hour ago")
}
Existing API for performing discrete (mouse wheel-like) scrolling on macOS swift · at 7:46 ↗
extension XCUIElement {

  // Use the existing API for discrete (mouse wheel-like) scrolling.
  open func scroll(byDeltaX: CGFloat, deltaY: CGFloat)

}
New API for performing continuous (trackpad-like) scrolling on macOS swift · at 8:05 ↗
extension XCUIElement {

  // Use the new API for continuous (trackpad-like) scrolling.
  open func swipeUp(velocity: XCUIGestureVelocity = .default)
  open func swipeDown(velocity: XCUIGestureVelocity = .default)
  open func swipeLeft(velocity: XCUIGestureVelocity = .default)
  open func swipeRight(velocity: XCUIGestureVelocity = .default)

}

Resources