Scroll until element is visible iOS UI Automation with xcode7

CodeGeass picture CodeGeass · Sep 18, 2015 · Viewed 28.5k times · Source

So with the new xcode update apple has revamped the way we do UI testing. In instruments we used java script function "isVisible" to determine if our targeted element is visible.

I'm trying to replicate this in objective c but i can't seem to find the equivalent of this. I have a table view, a prototype cell with two labels on it. This prototype cell is reused 50 times lets say.

I'm trying to scroll until the last cell is visible, i did this by doing this:

if (![[[[[[XCUIApplication alloc] init].tables childrenMatchingType:XCUIElementTypeCell] matchingIdentifier:@"cell"] elementBoundByIndex:49].staticTexts[@"text"] exists]) {
        [[[[[[XCUIApplication alloc] init].tables childrenMatchingType:XCUIElementTypeCell] matchingIdentifier:@"cell"] elementBoundByIndex:0].staticTexts[@"text"] swipeUp];
}

But this won't swipe since the element exists when the view is loaded. Please help cause this is driving me crazy.

Answer

Kádi picture Kádi · Nov 29, 2015

You should extend the XCUIElement's method list. The first method (scrollToElement:) will be called on the tableView, the second extension method helps you decide if the element is on the main window.

extension XCUIElement {

    func scrollToElement(element: XCUIElement) {
        while !element.visible() {
            swipeUp()
        }
    }

    func visible() -> Bool {
        guard self.exists && !CGRectIsEmpty(self.frame) else { return false }
        return CGRectContainsRect(XCUIApplication().windows.elementBoundByIndex(0).frame, self.frame)
    }

}

The scrolling code should look like this (e.g. scrolling to last cell):

func testScrollTable() {
    let app = XCUIApplication()
    let table = app.tables.elementBoundByIndex(0)
    let lastCell = table.cells.elementBoundByIndex(table.cells.count-1)
    table.scrollToElement(lastCell)
}

Swift 3:

extension XCUIElement {
    func scrollToElement(element: XCUIElement) {
        while !element.visible() {
            swipeUp()
        }
    }

    func visible() -> Bool {
        guard self.exists && !self.frame.isEmpty else { return false }
        return XCUIApplication().windows.element(boundBy: 0).frame.contains(self.frame)
    }
}