Combine the Server Selection screen into the Server Confirmation screen and add autocompletion when entering an account provider. (#5949)

* Adjust login flow to exclusively use the ServerSelectionScreen

* Move async code to server selection vm

* ServerSelection supports pro picker options

* Use homeserver address for both confirmation and picker modes

* rename ServerSelectionScreenMode

* remove ServerConfirmationScreen

It's been superseded by the ServerSelectionScreen

* rename userInput

* Update strings with latest design strings

* Add server input autocompletion

* Store previous servers in AppSettings and autofill on server signin

* Audit changes for logging

* Enforce lowercase server history storage

* Update tests

* Update Xcode project

* PR review fixups

* Add HomeserverHistoryManager

* Review fixups 2

* Review fixups 3
This commit is contained in:
Michael
2026-08-10 12:38:37 -05:00
committed by GitHub
parent 42a7b6e8ee
commit 6efa8743ff
71 changed files with 977 additions and 1357 deletions
@@ -20,18 +20,10 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase {
// Splash Screen: Tap get started button
app.buttons[A11yIdentifiers.authenticationStartScreen.signIn].tap()
// Server Confirmation: Tap change server button
app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer].tap()
// Server Selection: Clear the default, enter OAuth server and continue.
// Server Selection: Clear the default, enter a server address and submit.
// The \n triggers confirm directly, navigating to the login screen.
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("example.com\n", app: app)
// Await for the button to be hittable, since a loader may appear
let serverConfirmationContinueButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.continue]
XCTAssertTrue(serverConfirmationContinueButton.wait(for: \.isHittable, toEqual: true, timeout: 2.0))
// Server Confirmation: Tap continue button
serverConfirmationContinueButton.tap()
// Login Screen: Wait for continue button to appear
let continueButton = app.buttons[A11yIdentifiers.loginScreen.continue]
XCTAssertTrue(continueButton.waitForExistence(timeout: 2.0))
@@ -53,18 +45,10 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase {
// Splash Screen: Tap get started button
app.buttons[A11yIdentifiers.authenticationStartScreen.signIn].tap()
// Server Confirmation: Tap change server button
app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer].tap()
// Server Selection: Clear the default, enter OAuth server and continue.
// Server Selection: Clear the default, enter a server address and submit.
// The \n triggers confirm directly, navigating to the login screen.
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("example.com\n", app: app)
// Await for the button to be hittable, since a loader may appear
let serverConfirmationContinueButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.continue]
XCTAssertTrue(serverConfirmationContinueButton.wait(for: \.isHittable, toEqual: true, timeout: 2.0))
// Server Confirmation: Tap continue button
serverConfirmationContinueButton.tap()
// Login Screen: Wait for continue button to appear
let continueButton = app.buttons[A11yIdentifiers.loginScreen.continue]
XCTAssertTrue(continueButton.waitForExistence(timeout: 2.0))
@@ -88,18 +72,10 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase {
// Splash Screen: Tap get started button
app.buttons[A11yIdentifiers.authenticationStartScreen.signIn].tap()
// Server Confirmation: Tap change server button
app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer].tap()
// Server Selection: Clear the default, enter OAuth server and continue.
// Server Selection: Clear the default, enter a server address and submit.
// The \n triggers confirm directly, navigating to the login screen.
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("example.com\n", app: app)
// Await for the button to be hittable, since a loader may appear
let serverConfirmationContinueButton = app.buttons[A11yIdentifiers.serverConfirmationScreen.continue]
XCTAssertTrue(serverConfirmationContinueButton.wait(for: \.isHittable, toEqual: true, timeout: 2.0))
// Server Confirmation: Tap continue button
serverConfirmationContinueButton.tap()
// Login Screen: Wait for continue button to appear
let continueButton = app.buttons[A11yIdentifiers.loginScreen.continue]
XCTAssertTrue(continueButton.waitForExistence(timeout: 2.0))
@@ -125,9 +101,6 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase {
// Splash Screen: Tap get started button
app.buttons[A11yIdentifiers.authenticationStartScreen.signIn].tap()
// Server Confirmation: Tap change server button
app.buttons[A11yIdentifiers.serverConfirmationScreen.changeServer].tap()
// Server Selection: Clear the default, enter OAuth server and continue.
app.textFields[A11yIdentifiers.changeServerScreen.server].clearAndTypeText("company.com\n", app: app)
@@ -139,8 +112,8 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase {
// Keep looping on the Continue button for ~5 minutes until the Authentication Session is happy.
var remainingAttempts = 30
while !wasAlertText.exists {
// Server Confirmation: Tap continue button
app.buttons[A11yIdentifiers.serverConfirmationScreen.continue].tap()
// Server Selection: Tap continue button
app.buttons[A11yIdentifiers.changeServerScreen.continue].tap()
if wasAlertText.waitForExistence(timeout: 10) {
break
@@ -223,9 +196,11 @@ class AuthenticationFlowCoordinatorUITests: XCTestCase {
// Splash Screen: Tap get started button
app.buttons[A11yIdentifiers.authenticationStartScreen.signIn].tap()
// Server Confirmation: Tap the picker and confirm
app.switches.matching(identifier: A11yIdentifiers.serverConfirmationScreen.serverPicker).element(boundBy: 1).tap()
app.buttons[A11yIdentifiers.serverConfirmationScreen.continue].tap()
// Server Selection: Tap the second server in the picker and confirm.
// Use descendants(matching: .any) since ListRow used outside a List produces an ambiguous
// accessibility element type, making element-type-specific queries unreliable.
app.descendants(matching: .any).matching(identifier: "example.com").firstMatch.tap()
app.buttons[A11yIdentifiers.changeServerScreen.continue].tap()
// Login Screen: Wait for continue button to appear
let continueButton = app.buttons[A11yIdentifiers.loginScreen.continue]