From c409b16182f33140b8b06318f27e502e183f2668 Mon Sep 17 00:00:00 2001 From: Doug Date: Wed, 9 Oct 2024 16:52:13 +0100 Subject: [PATCH] Ask the iPad to reveal the keyboard when it's hidden. --- .../Sources/Other/Extensions/XCUIElement.swift | 18 +++++++++++++++++- UITests/Sources/AppLockSetupUITests.swift | 6 ++++-- .../AuthenticationFlowCoordinatorUITests.swift | 12 ++++++------ UITests/Sources/BugReportUITests.swift | 4 ++-- .../Sources/RoomMembersListScreenUITests.swift | 4 ++-- UITests/Sources/ServerSelectionUITests.swift | 2 +- UITests/Sources/StartChatScreenUITests.swift | 4 ++-- 7 files changed, 34 insertions(+), 16 deletions(-) diff --git a/ElementX/Sources/Other/Extensions/XCUIElement.swift b/ElementX/Sources/Other/Extensions/XCUIElement.swift index 83c26a615f..4d7436a1f1 100644 --- a/ElementX/Sources/Other/Extensions/XCUIElement.swift +++ b/ElementX/Sources/Other/Extensions/XCUIElement.swift @@ -8,9 +8,11 @@ import XCTest extension XCUIElement { - func clearAndTypeText(_ text: String) { + func clearAndTypeText(_ text: String, app: XCUIApplication) { tapCenter() + app.showKeyboardIfNeeded() + guard let currentValue = value as? String else { XCTFail("Tried to clear and type text into a non string value") return @@ -29,3 +31,17 @@ extension XCUIElement { coordinate.tap() } } + +extension XCUIApplication { + /// Ensures the software keyboard is shown on an iPad when a text field is focussed. + /// + /// Note: Whilst this could be added on XCUIElement to more closely tie it to a text field, it requires the + /// app instance anyway, and some of our tests assert that a default focus has been set on the text field, + /// so having a method that would set the focus and show the keyboard isn't always desirable. + func showKeyboardIfNeeded() { + if UIDevice.current.userInterfaceIdiom == .pad, keyboards.count == 0 { + buttons["Keyboard"].tap() + buttons["Show Keyboard"].tap() + } + } +} diff --git a/UITests/Sources/AppLockSetupUITests.swift b/UITests/Sources/AppLockSetupUITests.swift index 0911636358..5c2660af90 100644 --- a/UITests/Sources/AppLockSetupUITests.swift +++ b/UITests/Sources/AppLockSetupUITests.swift @@ -119,6 +119,8 @@ class AppLockSetupUITests: XCTestCase { func testCancel() async throws { app = Application.launch(.appLockSetupFlowUnlock) + app.showKeyboardIfNeeded() // The secure text field is focussed automatically + // Create PIN screen. try await app.assertScreenshot(.appLockSetupFlowUnlock) @@ -134,13 +136,13 @@ class AppLockSetupUITests: XCTestCase { let textField = app.secureTextFields[A11yIdentifiers.appLockSetupPINScreen.textField] XCTAssert(textField.waitForExistence(timeout: 10)) - textField.clearAndTypeText("2023") + textField.clearAndTypeText("2023", app: app) } private func enterDifferentPIN() { let textField = app.secureTextFields[A11yIdentifiers.appLockSetupPINScreen.textField] XCTAssert(textField.waitForExistence(timeout: 10)) - textField.clearAndTypeText("2233") + textField.clearAndTypeText("2233", app: app) } } diff --git a/UITests/Sources/AuthenticationFlowCoordinatorUITests.swift b/UITests/Sources/AuthenticationFlowCoordinatorUITests.swift index 0e38601c4b..40ff6d82c9 100644 --- a/UITests/Sources/AuthenticationFlowCoordinatorUITests.swift +++ b/UITests/Sources/AuthenticationFlowCoordinatorUITests.swift @@ -24,8 +24,8 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase { XCTAssertTrue(continueButton.waitForExistence(timeout: 2.0)) // Login Screen: Enter valid credentials - app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice\n") - app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("12345678") + app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice\n", app: app) + app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("12345678", app: app) try await app.assertScreenshot(.authenticationFlow) @@ -48,8 +48,8 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase { XCTAssertTrue(continueButton.waitForExistence(timeout: 2.0)) // Login Screen: Enter invalid credentials - app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice") - app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("87654321") + app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("alice", app: app) + app.secureTextFields[A11yIdentifiers.loginScreen.password].clearAndTypeText("87654321", app: app) // Login Screen: Tap continue XCTAssertTrue(continueButton.isEnabled) @@ -74,7 +74,7 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase { XCTAssertTrue(continueButton.waitForExistence(timeout: 2.0)) // When entering a username on a homeserver with an unsupported flow. - app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("@test:server.net\n") + app.textFields[A11yIdentifiers.loginScreen.emailUsername].clearAndTypeText("@test:server.net\n", app: app) // Then the screen should not allow login to continue. try await app.assertScreenshot(.authenticationFlow, step: 1) @@ -91,7 +91,7 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase { app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer].tap() // Server Selection: Clear the default, enter OIDC server and continue. - app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("company.com\n") + app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("company.com\n", app: app) // Server Confirmation: Tap continue button app.buttons[A11yIdentifiers.serverConfirmationScreen.continue].tap() diff --git a/UITests/Sources/BugReportUITests.swift b/UITests/Sources/BugReportUITests.swift index 03b8ec214c..d87441c964 100644 --- a/UITests/Sources/BugReportUITests.swift +++ b/UITests/Sources/BugReportUITests.swift @@ -20,13 +20,13 @@ class BugReportUITests: XCTestCase { let app = Application.launch(.bugReport) // Type 4 characters and the send button should be disabled. - app.textViews[A11yIdentifiers.bugReportScreen.report].clearAndTypeText("Text") + app.textViews[A11yIdentifiers.bugReportScreen.report].clearAndTypeText("Text", app: app) XCTAssert(app.switches[A11yIdentifiers.bugReportScreen.sendLogs].isOn) XCTAssert(!app.switches[A11yIdentifiers.bugReportScreen.canContact].isOn) try await app.assertScreenshot(.bugReport, step: 2) // Type more than 4 characters and send the button should become enabled. - app.textViews[A11yIdentifiers.bugReportScreen.report].clearAndTypeText("Longer text") + app.textViews[A11yIdentifiers.bugReportScreen.report].clearAndTypeText("Longer text", app: app) XCTAssert(app.switches[A11yIdentifiers.bugReportScreen.sendLogs].isOn) XCTAssert(!app.switches[A11yIdentifiers.bugReportScreen.canContact].isOn) try await app.assertScreenshot(.bugReport, step: 3) diff --git a/UITests/Sources/RoomMembersListScreenUITests.swift b/UITests/Sources/RoomMembersListScreenUITests.swift index 3bcecdfcfe..dc4c296498 100644 --- a/UITests/Sources/RoomMembersListScreenUITests.swift +++ b/UITests/Sources/RoomMembersListScreenUITests.swift @@ -19,7 +19,7 @@ class RoomMembersListScreenUITests: XCTestCase { let app = Application.launch(.roomMembersListScreenPendingInvites) let searchBar = app.searchFields.firstMatch - searchBar.clearAndTypeText("alice\n") + searchBar.clearAndTypeText("alice\n", app: app) try await app.assertScreenshot(.roomMembersListScreenPendingInvites, step: 1) } @@ -28,7 +28,7 @@ class RoomMembersListScreenUITests: XCTestCase { let app = Application.launch(.roomMembersListScreenPendingInvites) let searchBar = app.searchFields.firstMatch - searchBar.clearAndTypeText("bob\n") + searchBar.clearAndTypeText("bob\n", app: app) try await app.assertScreenshot(.roomMembersListScreenPendingInvites, step: 2) } diff --git a/UITests/Sources/ServerSelectionUITests.swift b/UITests/Sources/ServerSelectionUITests.swift index f5003421c3..02ac4b9a73 100644 --- a/UITests/Sources/ServerSelectionUITests.swift +++ b/UITests/Sources/ServerSelectionUITests.swift @@ -34,7 +34,7 @@ class ServerSelectionUITests: XCTestCase { let app = Application.launch(.serverSelection) // When typing in an invalid homeserver - app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("thisisbad\n") // The tests only accept an address from LoginHomeserver.mockXYZ + app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("thisisbad\n", app: app) // The tests only accept an address from LoginHomeserver.mockXYZ // Then an error should be shown and the confirmation button disabled. try await app.assertScreenshot(.serverSelection, step: 2) diff --git a/UITests/Sources/StartChatScreenUITests.swift b/UITests/Sources/StartChatScreenUITests.swift index 66a8e37c7f..63d09893e6 100644 --- a/UITests/Sources/StartChatScreenUITests.swift +++ b/UITests/Sources/StartChatScreenUITests.swift @@ -17,7 +17,7 @@ class StartChatScreenUITests: XCTestCase { func testSearchWithNoResults() async throws { let app = Application.launch(.startChat) let searchField = app.searchFields.firstMatch - searchField.clearAndTypeText("None\n") + searchField.clearAndTypeText("None\n", app: app) XCTAssert(app.staticTexts[A11yIdentifiers.startChatScreen.searchNoResults].waitForExistence(timeout: 1.0)) try await app.assertScreenshot(.startChat, step: 1) } @@ -25,7 +25,7 @@ class StartChatScreenUITests: XCTestCase { func testSearchWithResults() async throws { let app = Application.launch(.startChatWithSearchResults) let searchField = app.searchFields.firstMatch - searchField.clearAndTypeText("Bob\n") + searchField.clearAndTypeText("Bob\n", app: app) XCTAssertFalse(app.staticTexts[A11yIdentifiers.startChatScreen.searchNoResults].waitForExistence(timeout: 1.0)) XCTAssertEqual(app.collectionViews.firstMatch.cells.count, 2) try await app.assertScreenshot(.startChat, step: 2)