I started writing UI tests for my upcoming dungeon crawler game. My game engine uses SceneKit for the 3D world and XCUI tests for the UI test automation.
I recommend this tutorial as introduction in ui test automation with XCUI.
I write this tutorial because there is not much information avilable about the combination of SCNKit and XCUI. Hopefully it helps to avoid some of the pitfalls.
The specific problem I had to solve, was to automate a scenario, where two or more interactive SCNNodes are visible on a screen. Every node should trigger a different action.
Using screen coordinates to trigger a specific node, would have been one option, but this causes a huge overhead. My game runs on iPads and iPhones in Landscape and Portrait format. That means for each combination of screen resolution and orientation I would need different sets of coordinates.
Here is a much better solution:
I subclassed SCNNode and implemented the UIAccessibilityIdentification delegate. Every time I created an instance of MyNode I gave it a unique accessibilityIdentifier.
class MyNode: SCNNode, UIAccessibilityIdentification {
var accessibilityIdentifier: String?
}
Now these nodes can be addressed inside of the test code with:
app.otherElements[id].firstMatch
My first try was to get the element and call the tap method directly on the node:
app.otherElements[id].firstMatch.tap()
Unfortunately that didn’t work. An SCNNode doesn’t react on the tap method in XCUI.
The trick was to find the SCNNode, get the coordinates of the node and call tap on these coordinates:
app.otherElements[id].firstMatch.coordinate(withNormalizedOffset: CGVector.zero).tap()
And here is a video with the automated result. The left button closes the pit and the right opens the door.
That all for today,
Cheers Stefan