Xcode UI Test:Accessibility Query Fail on Uitableviewcell

Xcode UI test : Accessibility query fail on UITableViewCell

I found the answer here. In order to make the UITableViewCell accessible, the containing UITableView cannot be accessible itself.

So, you just need to remove these lines:

tableView.isAccessibilityElement = true
tableView.accessibilityLabel = "Thetable"
tableView.accessibilityIdentifier = "Thetable"

Test for UITableViewCell existence failing from inside a split view controller

I encountered the same problem when trying to test for tableview cell existence on the simulator. On a simulated iPhone device the test would succeed, whereas on an iPad device it would fail.

I found that the problem lay in the fact that a UITest that references a table will fail if the app's current view does not have the tableview whose data you would like to test. On an iPhone the view by default had a back button that would transition the app from its detail view back to the master viewcontroller which contained the tableview. On the iPad simulator this back button was not there, and so it could not transition correctly to the tableview's view, making the entire test fail.

func testTableCellsExist() {

let app = XCUIApplication()
app.launch()

app.navigationBars["AppName.DetailView"].buttons["Root View Controller"].tap()

let tablesQuery = app.tables["MasterTable"]

let testCell = tablesQuery.cells.element(boundBy: 49)
XCTAssert(tablesQuery.cells.count == 50)
XCTAssert(testCell.exists)
}

What I did to make the test succeed for both iPad and iPhone device simulations was to make it so that the app would launch and display the tableview's viewcontroller at the outset. This was done by adding this code to the UISplitViewController swift file:

class SplitViewController: UISplitViewController {

override func viewDidLoad() {
super.viewDidLoad()
self.delegate = self
self.preferredDisplayMode = .allVisible
}

}

extension SplitViewController: UISplitViewControllerDelegate {
func splitViewController(
_ splitViewController: UISplitViewController,
collapseSecondary secondaryViewController: UIViewController,
onto primaryViewController: UIViewController) -> Bool {
// Return true to prevent UIKit from applying its default behavior
return true
}

}

The explanation for the above code can be found here:

Open UISplitViewController to Master View rather than Detail

Regardless, after the above modification, the assertions for tableview cell existence should now succeed even on an iPad because the view is now correctly set to the view which has the tableview being queried.

If you don't want your app to start with this view by default, then you'll have to make sure that your test code transitions to the tableview's view before the assertions are made.

Also, if you follow my example through, be sure to remove this line in the test case, because it no longer becomes necessary to navigate to the tableview's VC after the modifications to the UISplitViewController code:

app.navigationBars["AppName.DetailView"].buttons["Root View Controller"].tap()

UPDATE (October 25): Master Detail App Project - Basic TableView Existence Test

I attempted to create a basic Master Detail app as you suggested, and tried the test as well. A basic test for the tableview failed again with me when I selected an iPad device to simulate, because it shows only the detail view (no table). I modified my test so that if the device is an iPad, it will check its orientation, and set the landscape orientation as required, before checking for the table's existence. I only modified the test and nothing else, and what was previously a failure became a success. I also set the accesibility identifier for the tableview in the MasterVC's viewDidLoad, but I believe the results would be the same whether we set the identifier or not. Here's the test code:

func testExample() {
// UI tests must launch the application that they test.
let app = XCUIApplication()
app.launch()

// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.

if UIDevice.current.userInterfaceIdiom == .pad {

print("TESTING AN IPAD\n")
print(XCUIDevice.shared.orientation.rawValue)

// For some reason isPortrait returns false
// If rawValue == 0 it also seems to indicate iPad in portrait mode
if (XCUIDevice.shared.orientation.isPortrait || XCUIDevice.shared.orientation.rawValue == 0){
XCUIDevice.shared.orientation = .landscapeRight
}
XCTAssert(app.tables["MyTable"].exists)
//XCTAssert(app.tables["MyTable"].waitForExistence(timeout: 5.0))
} else if UIDevice.current.userInterfaceIdiom == .phone {
print("TESTING AN IPHONE\n")
XCTAssert(app.tables["MyTable"].exists)
}

// XCTAssert(app.tables["MyTable"].exists)

}

I added an else for the iPhone case, and print logs to say which type of device is being tested. Whether .exists or .waitForExistence is used, the tests should always succeed. But as was pointed out, .waitForExistence is better in the case where the table view takes time to load up.

Hope this helps. Cheers!

UPDATE (OCTOBER 27): Test Fails on a Real iPad

OP has discerned that the test -- which succeeds for simulated iPhone and iPad devices -- fails on a real device (for more information, please check his informative comment for this answer below). As the test failed on a real iPad which was already in landscape mode (see screenshot), it may be assumed that XC UITest functionality is broken in this regard.

In any case I hope these tests and results will prove helpful (they certainly taught me a thing or two) to others as well.

Cheers :D

How to validate UITableviewCell label and Imageview data with UI Test Cases

Use following to compare text for label value

let app = XCUIApplication()
let myTable = app.tables["property_list_tableview"]
XCTAssertEqual(myTable.cells["cell_0"].staticTexts["field_name"].label, "Text to compare")

In XCUITest deeply nested elements have wrong accessibility features

I had a similar problem.
It helped me to use accessibilityElements in TableViewCell (I found the advice here Custom UITableViewCell accessibility)

Try to set in your TableViewCell

accessibilityElements = [CollectionView] 


Related Topics



Leave a reply



Submit