Search code examples
iosios-ui-automationxcode-ui-testing

generic tap function for XCUIApplication


We are trying to migrate from UIAutomation to XCUITests. For the UIAutomation we came up with a handy 'tapOnName' function which just crawled thru a whole sub element tree and tapped on the element with the first match.

function log(msg) {
  UIALogger.logDebug(msg);
}
//recursive function crawling thru an elements hierarchy
//and tapping on the first match of accessibilityIdentifier
//or button text
function tapOnNameWithRoot(name,el) {
  if (el.name()==name && el.isVisible()) {
    log("tap on itt!!!")
    el.tap();
    return true;
  } 
  if (el.toString()=="[object UIAButton]" && el.label()==name) {
    log("tap on Button!!!")
    el.tap();
    return true;
  }
  var elements=el.elements();
  if (elements===null || elements===undefined) {
    log("elements null or undefined for:"+el.toString());
    return false; 
  }
  for(var i=0,len=elements.length ;i<len;i++) {
    if (tapOnNameWithRoot(name,elements[i])) {
      return true;
    }
  }
  return false;
}
var win = UIATarget.localTarget().frontMostApp().mainWindow();
//for ex taps on a button with the text "pushme" in the 
//main UIWindow
tapOnNameWithRoot("pushme",win);

No the question : is it possible to implement the same function using XCUIApplication ?


Solution

  • There is shorthand support for this function in XCTest.

    For tapping the first match out of any element, you can get all elements and tap the first one:

    let app = XCUIApplication()
    let element = app.descendentsMatchingType(.Any)["someIdentifier"]
    element.tap()
    

    If you know what type of element it is going to be, it's better to filter by that type first:

    let app = XCUIApplication()
    let element = app.buttons["someIdentifier"]
    element.tap()