Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Replicate pull to refresh in XCTest UI testing

Tags:

I am trying to replicate a pull to refresh on a UITableView using the new Xcode UI testing framework in Xcode 7 (beta 3)

My current approach is dragging from the table to whatever element below the table I can find. This works when there is a fixed item below the table like a UIToolbar or UITabBar I would rather not rely on having a UITabBar or UIToolbar but I can't figure out a way to do the pull to refresh/drag action without using the method in XCUIElement.

func pressForDuration(duration: NSTimeInterval, thenDragToElement otherElement: XCUIElement) 

Refresh success

But it fails when I don't have a toolbar/tabbar and try to drag using the cells

Refresh failure

This is the relevant portion of my code:

func testRefresh() {     //For testing cell     for _ in 0...9 {         addCell()     }     refreshTable() }  func refreshTable(var tbl: XCUIElement? = nil) {     let app = XCUIApplication()      if tbl == nil {         let tables = app.tables         if tables.count > 0 {             tbl = tables.elementAtIndex(0)         }     }      guard let table = tbl else {         XCTFail("Cannot find a table to refresh, you can provide on explicitly if you do have a table")         return     }      var topElement = table     let bottomElement: XCUIElement?      //Try to drag to a tab bar then to a toolbar then to the last cell     if app.tabBars.count > 0 {         bottomElement = app.tabBars.elementAtIndex(0)     }     else if app.toolbars.count > 0 {         bottomElement = app.toolbars.elementAtIndex(0)     }     else {         let cells = app.cells         if cells.count > 0 {             topElement = cells.elementAtIndex(0)             bottomElement = cells.elementAtIndex(cells.count - 1)         }         else {             bottomElement = nil         }     }     if let dragTo = bottomElement {         topElement.pressForDuration(0.1, thenDragToElement: dragTo)     } }  func addCell() {     let app = XCUIApplication()     app.navigationBars["Master"].buttons["Add"].tap() } 

Additional failed attempts:

  • swipeDown() (multiples times as well)
  • scrollByDeltaX/deltaY (OS X only)
like image 721
Kevin Avatar asked Jul 08 '15 19:07

Kevin


People also ask

What is XCTest XCUITest?

Key Concepts of XCUITest XCTest: XCTest is a testing framework that allows you to create and run UI tests, unit tests, and performance tests for your Xcode projects in Swift and Objective-C languages. It is pre-built with Xcode.

Which test framework does XCUITest use?

XCUITest is an iOS testing framework developed by Apple in 2015 for its native UI suite. It is developed on top of the XCTest framework which is the main test framework that is integrated within Apple's Xcode. The XCUITest tests can be written on XCode, using Swift or Objective-C.

What is XCTest used for?

Overview. Use the XCTest framework to write unit tests for your Xcode projects that integrate seamlessly with Xcode's testing workflow. Tests assert that certain conditions are satisfied during code execution, and record test failures (with optional messages) if those conditions aren't satisfied.

What is XCTest file?

A testing framework that allows to create and run unit tests, performance tests, and UI tests for your Xcode project. Tests assert that certain conditions are satisfied during code execution, and record test failures if those conditions are not satisfied. Developed by. Apple. Open-source.


1 Answers

You can use the XCUICoordinate API to interact with specific points on the screen, not necessarily tied to any particular element.

  1. Grab a reference to the first cell in your table. Then create a coordinate with zero offset, CGVectorMake(0, 0). This will normalize a point right on top of the first cell.
  2. Create an imaginary coordinate farther down the screen. (I've found that a dy of six is the smallest amount needed to trigger the pull-to-refresh gesture.)
  3. Execute the gesture by grabbing the first coordinate and dragging it to the second one.

enter image description here

let firstCell = app.staticTexts["Adrienne"] let start = firstCell.coordinateWithNormalizedOffset(CGVectorMake(0, 0)) let finish = firstCell.coordinateWithNormalizedOffset(CGVectorMake(0, 6)) start.pressForDuration(0, thenDragToCoordinate: finish) 

More information along with a working sample app is also available.

like image 121
Joe Masilotti Avatar answered Sep 29 '22 21:09

Joe Masilotti