If we have the following view:
import SwiftUI
struct MyView: View {
var body: some View {
Text("Bar")
.accessibilityLabel("Foo")
.accessibilityIdentifier("myTextThing")
}
}
Is there any way at all in a UI test to check the displayed content?
It seems that setting an accessibilityLabel
means that the displayed content becomes inaccessible:
import XCTest
final class MyUITest: XCTestCase {
@MainActor
func testExample() throws {
let app = XCUIApplication()
app.launch()
let targetElement = app.staticTexts["myTextThing"]
XCTAssert(targetElement.exists)
// Following assert checks the only the *accessibility* label
XCTAssertEqual(targetElement.label, "Foo") // PASSES
// If there was no .accessibilityLabel set we could check the displayed content like this:
// XCTAssertEqual(targetElement.label, "Bar")
// ...although that would actually just be validating
// the element's auto-generated accessibilityLabel
}
}
I've been unable to find a way to write an assertion in a UI test which validates that what is displayed in the UI is 'Bar', in addition to the above which validates that the accessibility label is 'Foo'.
Resources I've found on this so far (primarily somewhat circular "Yes you can do totally this!, Noooo you can't actually do this..." conversions with LLMs) seem to suggest that the solution is to test any logic in unit tests. That way there should be no surprises about what labels are being displayed, so you shouldn't require covering that in UI test cases.
Essentially it seems that the testing surface exposed by the XCUI framework is not just hooked into accessibility, but only accessibility, and nothing else.
I'm in the process of improving accessibility within an app which does not have a lot of existing accessibility features. It has comprehensive UI tests, but those have primarily been written to validate what is displayed on-screen.
Updating these tests as accessibility features are built-out means that the tests are gradually moving from testing what is displayed to testing purely what the app 'looks like' from an accessibility perspective. In some cases the displayed elements and their accessibility labels differ, such as:
CustomSectionView {
Text("Cars")
}
.accessibilityLabel("Section, Cars")
Previously a UI test here would have effectively verified that the displayed element was "Cars". Now the test only verifies that the accessibility label is "Section, Cars", with no-longer specific coverage (in the UI tests at least) that "Cars" is displayed on-screen.
Not as far as I know. By defining accessibilityLabel
you are effectively overriding the standard assigned label
property of the element seen by XCUITest, which otherwise would contain your visible string.