Align accessibility IDs with elementX android (#567)

* Rename onboarding and login user/pass accessibility ids.

* Refactor remaining server change accessibility IDs

* Avoid accessibilityIdentifier spreading to all decorations on the textBox.

Required because otherwise there are multiple items tagged with the accessibilityId
which means we can't click on "the" item.

* Move all accessibility identifiers to `AccessibilityIdentifiers.swft`
- use same naming convention on all of them
- remove the unused ones
- fix build errors in integration tests and invalid identifiers (still broken until autodiscovery lands on rosa)

---------

Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
This commit is contained in:
Michael Kaye
2023-02-15 05:53:04 +00:00
committed by GitHub
parent 21154c7eef
commit a06365517c
29 changed files with 215 additions and 141 deletions
@@ -25,17 +25,17 @@ class AuthenticationCoordinatorUITests: XCTestCase {
let app = Application.launch(.authenticationFlow)
// Splash Screen: Tap get started button
app.buttons["getStartedButton"].tap()
app.buttons[A11yIdentifiers.onboardingScreen.signIn].tap()
// Login Screen: Enter valid credentials
app.textFields["usernameTextField"].clearAndTypeText("alice\n")
app.secureTextFields["passwordTextField"].clearAndTypeText("12345678")
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice\n")
app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("12345678")
app.assertScreenshot(.authenticationFlow)
// Login Screen: Tap next
app.buttons["nextButton"].tap()
app.buttons[A11yIdentifiers.loginScreen.continue].tap()
// Then login should succeed.
XCTAssertFalse(app.alerts.element.exists, "No alert should be shown when logging in with valid credentials.")
@@ -46,14 +46,14 @@ class AuthenticationCoordinatorUITests: XCTestCase {
let app = Application.launch(.authenticationFlow)
// Splash Screen: Tap get started button
app.buttons["getStartedButton"].tap()
app.buttons[A11yIdentifiers.onboardingScreen.signIn].tap()
// Login Screen: Enter invalid credentials
app.textFields["usernameTextField"].clearAndTypeText("alice")
app.secureTextFields["passwordTextField"].clearAndTypeText("87654321")
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice")
app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("87654321")
// Login Screen: Tap next
let nextButton = app.buttons["nextButton"]
let nextButton = app.buttons[A11yIdentifiers.loginScreen.continue]
XCTAssertTrue(nextButton.waitForExistence(timeout: 2.0))
XCTAssertTrue(nextButton.isEnabled)
nextButton.tap()
@@ -67,19 +67,19 @@ class AuthenticationCoordinatorUITests: XCTestCase {
let app = Application.launch(.authenticationFlow)
// Splash Screen: Tap get started button
app.buttons["getStartedButton"].tap()
app.buttons[A11yIdentifiers.onboardingScreen.signIn].tap()
// Login Screen: Tap edit server button.
XCTAssertFalse(app.buttons["oidcButton"].exists, "The OIDC button shouldn't be shown before entering a supported homeserver.")
app.buttons["editServerButton"].tap()
XCTAssertFalse(app.buttons[A11yIdentifiers.loginScreen.oidc].exists, "The OIDC button shouldn't be shown before entering a supported homeserver.")
app.buttons[A11yIdentifiers.loginScreen.changeServer].tap()
// Server Selection: Clear the default and enter OIDC server.
app.textFields["addressTextField"].clearAndTypeText("company.com")
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("company.com")
// Dismiss server screen.
app.buttons["confirmButton"].tap()
app.buttons[A11yIdentifiers.changeServerScreen.continue].tap()
// Then the login form should be updated for OIDC.
XCTAssertTrue(app.buttons["oidcButton"].waitForExistence(timeout: 1), "The OIDC button should be shown after selecting a homeserver with OIDC.")
XCTAssertTrue(app.buttons[A11yIdentifiers.loginScreen.oidc].waitForExistence(timeout: 1), "The OIDC button should be shown after selecting a homeserver with OIDC.")
}
}
+8 -8
View File
@@ -28,9 +28,9 @@ class BugReportUITests: XCTestCase {
func testToggleSendingLogs() {
let app = Application.launch(.bugReport)
app.switches["sendLogsToggle"].tap()
app.switches[A11yIdentifiers.bugReportScreen.sendLogs].tap()
let sendingLogsToggle = app.switches["sendLogsToggle"]
let sendingLogsToggle = app.switches[A11yIdentifiers.bugReportScreen.sendLogs]
XCTAssert(sendingLogsToggle.exists)
XCTAssertFalse(sendingLogsToggle.isOn)
@@ -41,13 +41,13 @@ class BugReportUITests: XCTestCase {
let app = Application.launch(.bugReport)
// Type 4 characters and the send button should be disabled.
app.textViews["reportTextView"].clearAndTypeText("Text")
XCTAssertFalse(app.buttons["sendButton"].isEnabled)
app.textViews[A11yIdentifiers.bugReportScreen.report].clearAndTypeText("Text")
XCTAssertFalse(app.buttons[A11yIdentifiers.bugReportScreen.send].isEnabled)
app.assertScreenshot(.bugReport, step: 2)
// Type more than 4 characters and send the button should become enabled.
app.textViews["reportTextView"].clearAndTypeText("Longer text")
XCTAssert(app.buttons["sendButton"].isEnabled)
app.textViews[A11yIdentifiers.bugReportScreen.report].clearAndTypeText("Longer text")
XCTAssert(app.buttons[A11yIdentifiers.bugReportScreen.send].isEnabled)
app.assertScreenshot(.bugReport, step: 3)
}
@@ -55,8 +55,8 @@ class BugReportUITests: XCTestCase {
let app = Application.launch(.bugReportWithScreenshot)
// Initial state with a screenshot attached.
XCTAssert(app.images["screenshotImage"].exists)
XCTAssert(app.buttons["removeScreenshotButton"].exists)
XCTAssert(app.images[A11yIdentifiers.bugReportScreen.screenshot].exists)
XCTAssert(app.buttons[A11yIdentifiers.bugReportScreen.removeScreenshot].exists)
app.assertScreenshot(.bugReportWithScreenshot)
}
}
+4 -4
View File
@@ -25,8 +25,8 @@ class LoginScreenUITests: XCTestCase {
app.assertScreenshot(.login)
// When typing in a username and password.
app.textFields["usernameTextField"].clearAndTypeText("@test:matrix.org")
app.secureTextFields["passwordTextField"].clearAndTypeText("12345678")
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("@test:matrix.org")
app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("12345678")
// Then the form should be ready to submit.
app.assertScreenshot(.login, step: 0)
@@ -37,7 +37,7 @@ class LoginScreenUITests: XCTestCase {
let app = Application.launch(.login)
// When entering a username on a homeserver that only supports OIDC.
app.textFields["usernameTextField"].clearAndTypeText("@test:company.com\n")
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("@test:company.com\n")
// Then the screen should be configured for OIDC.
app.assertScreenshot(.login, step: 1)
@@ -48,7 +48,7 @@ class LoginScreenUITests: XCTestCase {
let app = Application.launch(.login)
// When entering a username on a homeserver with an unsupported flow.
app.textFields["usernameTextField"].clearAndTypeText("@test:server.net\n")
app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("@test:server.net\n")
// Then the screen should not allow login to continue.
app.assertScreenshot(.login, step: 2)
+1 -1
View File
@@ -30,7 +30,7 @@ class OnboardingUITests: XCTestCase {
// Given the splash screen in its initial state.
let page1TitleText = app.staticTexts[ElementL10n.ftueAuthCarouselSecureTitle]
let page2TitleText = app.staticTexts[ElementL10n.ftueAuthCarouselControlTitle]
let hiddenPageTitleText = app.staticTexts["hiddenPage"].firstMatch
let hiddenPageTitleText = app.staticTexts[A11yIdentifiers.onboardingScreen.hidden].firstMatch
XCTAssertTrue(page1TitleText.isHittable, "The title from the first page of the carousel should be onscreen.")
XCTAssertFalse(page2TitleText.isHittable, "The title from the second page of the carousel should be offscreen.")
@@ -21,14 +21,14 @@ class RoomDetailsScreenUITests: XCTestCase {
func testInitialStateComponents() {
let app = Application.launch(.roomDetailsScreen)
XCTAssert(app.staticTexts["roomAvatarImage"].exists)
XCTAssert(app.staticTexts[A11yIdentifiers.roomScreen.avatar].exists)
app.assertScreenshot(.roomDetailsScreen)
}
func testInitialStateComponentsWithRoomAvatar() {
let app = Application.launch(.roomDetailsScreenWithRoomAvatar)
XCTAssert(app.images["roomAvatarImage"].waitForExistence(timeout: 1))
XCTAssert(app.images[A11yIdentifiers.roomScreen.avatar].waitForExistence(timeout: 1))
app.assertScreenshot(.roomDetailsScreenWithRoomAvatar)
}
}
+4 -4
View File
@@ -24,8 +24,8 @@ class RoomScreenUITests: XCTestCase {
func testPlainNoAvatar() {
let app = Application.launch(.roomPlainNoAvatar)
XCTAssert(app.staticTexts["roomNameLabel"].exists)
XCTAssert(app.staticTexts["roomAvatarImage"].exists)
XCTAssert(app.staticTexts[A11yIdentifiers.roomScreen.name].exists)
XCTAssert(app.staticTexts[A11yIdentifiers.roomScreen.avatar].exists)
app.assertScreenshot(.roomPlainNoAvatar)
}
@@ -33,8 +33,8 @@ class RoomScreenUITests: XCTestCase {
func testEncryptedWithAvatar() {
let app = Application.launch(.roomEncryptedWithAvatar)
XCTAssert(app.staticTexts["roomNameLabel"].exists)
XCTAssert(app.images["roomAvatarImage"].waitForExistence(timeout: 1))
XCTAssert(app.staticTexts[A11yIdentifiers.roomScreen.name].exists)
XCTAssert(app.images[A11yIdentifiers.roomScreen.avatar].waitForExistence(timeout: 1))
app.assertScreenshot(.roomEncryptedWithAvatar)
}
+10 -12
View File
@@ -19,16 +19,14 @@ import XCTest
@MainActor
class ServerSelectionUITests: XCTestCase {
let textFieldIdentifier = "addressTextField"
func testNormalState() async {
// Given the initial server selection screen as a modal.
let app = Application.launch(.serverSelection)
// Then it should be configured for matrix.org
app.assertScreenshot(.serverSelection, step: 0)
XCTAssertEqual(app.textFields[textFieldIdentifier].value as? String, "matrix.org", "The server shown should be matrix.org with the https scheme hidden.")
XCTAssertEqual(app.buttons["confirmButton"].label, ElementL10n.continue, "The confirm button should say Confirm when in modal presentation.")
XCTAssertEqual(app.textFields[A11yIdentifiers.changeServerScreen.server].value as? String, "matrix.org", "The server shown should be matrix.org with the https scheme hidden.")
XCTAssertEqual(app.buttons[A11yIdentifiers.changeServerScreen.continue].label, ElementL10n.continue, "The confirm button should say Confirm when in modal presentation.")
}
func testEmptyAddress() async {
@@ -36,13 +34,13 @@ class ServerSelectionUITests: XCTestCase {
let app = Application.launch(.serverSelection)
// When clearing the server address text field.
app.textFields[textFieldIdentifier].tap()
app.textFields[textFieldIdentifier].buttons.element.tap()
app.textFields[A11yIdentifiers.changeServerScreen.server].tap()
app.textFields[A11yIdentifiers.changeServerScreen.server].buttons.element.tap()
// Then the screen should not allow the user to continue.
app.assertScreenshot(.serverSelection, step: 1)
XCTAssertEqual(app.textFields[textFieldIdentifier].value as? String, ElementL10n.ftueAuthChooseServerEntryHint, "The text field should show placeholder text in this state.")
XCTAssertFalse(app.buttons["confirmButton"].isEnabled, "The confirm button should be disabled when the address is empty.")
XCTAssertEqual(app.textFields[A11yIdentifiers.changeServerScreen.server].value as? String, ElementL10n.ftueAuthChooseServerEntryHint, "The text field should show placeholder text in this state.")
XCTAssertFalse(app.buttons[A11yIdentifiers.changeServerScreen.continue].isEnabled, "The confirm button should be disabled when the address is empty.")
}
func testInvalidAddress() {
@@ -50,12 +48,12 @@ class ServerSelectionUITests: XCTestCase {
let app = Application.launch(.serverSelection)
// When typing in an invalid homeserver
app.textFields[textFieldIdentifier].clearAndTypeText("thisisbad\n") // The tests only accept an address from LoginHomeserver.mockXYZ
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("thisisbad\n") // The tests only accept an address from LoginHomeserver.mockXYZ
// Then an error should be shown and the confirmation button disabled.
app.assertScreenshot(.serverSelection, step: 2)
XCTAssertTrue(app.staticTexts[ElementL10n.loginErrorHomeserverNotFound].exists)
XCTAssertFalse(app.buttons["confirmButton"].isEnabled, "The confirm button should be disabled when there is an error.")
XCTAssertFalse(app.buttons[A11yIdentifiers.changeServerScreen.continue].isEnabled, "The confirm button should be disabled when there is an error.")
}
func testNonModalPresentation() {
@@ -64,7 +62,7 @@ class ServerSelectionUITests: XCTestCase {
// Then the screen should be tweaked slightly to reflect the change of navigation.
app.assertScreenshot(.serverSelectionNonModal)
XCTAssertFalse(app.buttons["dismissButton"].exists, "The dismiss button should be hidden when not in modal presentation.")
XCTAssertEqual(app.buttons["confirmButton"].label, ElementL10n.actionNext, "The confirm button should say Next when not in modal presentation.")
XCTAssertFalse(app.buttons[A11yIdentifiers.changeServerScreen.dismiss].exists, "The dismiss button should be hidden when not in modal presentation.")
XCTAssertEqual(app.buttons[A11yIdentifiers.changeServerScreen.continue].label, ElementL10n.actionNext, "The confirm button should say Next when not in modal presentation.")
}
}
@@ -34,68 +34,68 @@ class SessionVerificationUITests: XCTestCase {
let app = Application.launch(.sessionVerification)
app.assertScreenshot(.sessionVerification, step: Step.initialState)
app.buttons["requestVerificationButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.requestVerification].tap()
app.assertScreenshot(.sessionVerification, step: Step.waitingForOtherDevice)
XCTAssert(app.buttons["sasVerificationStartButton"].waitForExistence(timeout: 5.0))
XCTAssert(app.buttons[A11yIdentifiers.sessionVerificationScreen.startSasVerification].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.useEmojiComparisonPrompt)
app.buttons["sasVerificationStartButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.startSasVerification].tap()
app.assertScreenshot(.sessionVerification, step: Step.waitingForEmojis)
XCTAssert(app.buttons["challengeAcceptButton"].waitForExistence(timeout: 5.0))
XCTAssert(app.buttons[A11yIdentifiers.sessionVerificationScreen.acceptChallenge].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.compareEmojis)
app.buttons["challengeAcceptButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.acceptChallenge].tap()
app.assertScreenshot(.sessionVerification, step: Step.acceptingEmojis)
XCTAssert(app.staticTexts[ElementL10n.verificationConclusionOkSelfNoticeTitle].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.verificationComplete)
app.buttons["closeButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.close].tap()
}
func testChallengeDoesNotMatch() {
let app = Application.launch(.sessionVerification)
app.assertScreenshot(.sessionVerification, step: Step.initialState)
app.buttons["requestVerificationButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.requestVerification].tap()
app.assertScreenshot(.sessionVerification, step: Step.waitingForOtherDevice)
XCTAssert(app.buttons["sasVerificationStartButton"].waitForExistence(timeout: 5.0))
XCTAssert(app.buttons[A11yIdentifiers.sessionVerificationScreen.startSasVerification].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.useEmojiComparisonPrompt)
app.buttons["sasVerificationStartButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.startSasVerification].tap()
app.assertScreenshot(.sessionVerification, step: Step.waitingForEmojis)
XCTAssert(app.buttons["challengeAcceptButton"].waitForExistence(timeout: 5.0))
XCTAssert(app.buttons[A11yIdentifiers.sessionVerificationScreen.acceptChallenge].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.compareEmojis)
app.buttons["challengeDeclineButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.declineChallenge].tap()
app.assertScreenshot(.sessionVerification, step: Step.verificationCancelled)
app.buttons["closeButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.close].tap()
}
func testSessionVerificationCancelation() {
let app = Application.launch(.sessionVerification)
app.assertScreenshot(.sessionVerification, step: Step.initialState)
app.buttons["requestVerificationButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.requestVerification].tap()
app.assertScreenshot(.sessionVerification, step: Step.waitingForOtherDevice)
XCTAssert(app.buttons["sasVerificationStartButton"].waitForExistence(timeout: 5.0))
XCTAssert(app.buttons[A11yIdentifiers.sessionVerificationScreen.startSasVerification].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.useEmojiComparisonPrompt)
app.buttons["sasVerificationStartButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.startSasVerification].tap()
app.assertScreenshot(.sessionVerification, step: Step.waitingForEmojis)
XCTAssert(app.buttons["challengeAcceptButton"].waitForExistence(timeout: 5.0))
XCTAssert(app.buttons[A11yIdentifiers.sessionVerificationScreen.acceptChallenge].waitForExistence(timeout: 5.0))
app.assertScreenshot(.sessionVerification, step: Step.compareEmojis)
app.buttons["closeButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.close].tap()
app.assertScreenshot(.sessionVerification, step: Step.verificationCancelled)
app.buttons["closeButton"].tap()
app.buttons[A11yIdentifiers.sessionVerificationScreen.close].tap()
}
}
+8 -8
View File
@@ -29,14 +29,14 @@ class SoftLogoutUITests: XCTestCase {
func testInitialState() {
app = Application.launch(.softLogout)
XCTAssertTrue(app.staticTexts["titleLabel"].exists, "The title should be shown.")
XCTAssertTrue(app.staticTexts["messageLabel1"].exists, "The message 1 should be shown.")
XCTAssertTrue(app.staticTexts["clearDataTitleLabel"].exists, "The clear data title should be shown.")
XCTAssertTrue(app.staticTexts["clearDataMessageLabel"].exists, "The clear data message should be shown.")
XCTAssertTrue(app.secureTextFields["passwordTextField"].exists, "The password text field should be shown.")
XCTAssertTrue(app.buttons["nextButton"].exists, "The next button should be shown.")
XCTAssertTrue(app.buttons["forgotPasswordButton"].exists, "The forgot password button should be shown.")
XCTAssertTrue(app.buttons["clearDataButton"].exists, "The clear data button should be shown.")
XCTAssertTrue(app.staticTexts[A11yIdentifiers.softLogoutScreen.title].exists, "The title should be shown.")
XCTAssertTrue(app.staticTexts[A11yIdentifiers.softLogoutScreen.message].exists, "The message 1 should be shown.")
XCTAssertTrue(app.staticTexts[A11yIdentifiers.softLogoutScreen.clearDataTitle].exists, "The clear data title should be shown.")
XCTAssertTrue(app.staticTexts[A11yIdentifiers.softLogoutScreen.clearDataMessage].exists, "The clear data message should be shown.")
XCTAssertTrue(app.secureTextFields[A11yIdentifiers.softLogoutScreen.password].exists, "The password text field should be shown.")
XCTAssertTrue(app.buttons[A11yIdentifiers.softLogoutScreen.next].exists, "The next button should be shown.")
XCTAssertTrue(app.buttons[A11yIdentifiers.softLogoutScreen.forgotPassword].exists, "The forgot password button should be shown.")
XCTAssertTrue(app.buttons[A11yIdentifiers.softLogoutScreen.clearData].exists, "The clear data button should be shown.")
app.assertScreenshot(.softLogout)
}
+1 -1
View File
@@ -26,7 +26,7 @@ class UserSessionScreenTests: XCTestCase {
app.assertScreenshot(.userSessionScreen, step: 1)
app.buttons["roomName:\(roomName)"].tap()
app.buttons[A11yIdentifiers.homeScreen.roomName(roomName)].tap()
XCTAssert(app.staticTexts[roomName].waitForExistence(timeout: 5.0))