mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-10-31 08:15:24 +00:00
Fix integration tests following the search tab introduction
Tabbar tabs now can take accessibility identifiers and the integration test uses the newly expected flow.
This commit is contained in:
@@ -26,18 +26,20 @@ import SwiftUI
|
||||
/// When `true` the tab is given the `.search` role, which on iOS 26 detaches it
|
||||
/// into the trailing search button in the tab bar.
|
||||
let isSearch: Bool
|
||||
let accessibilityIdentifier: String?
|
||||
var badgeCount = 0
|
||||
|
||||
/// Provide the tab's split coordinator in here to have the tab bar automatically hidden
|
||||
/// when pushing a child into the split view's details on iPhone/compact iPad.
|
||||
weak var navigationSplitCoordinator: NavigationSplitCoordinator?
|
||||
|
||||
init(tag: Tag, title: String, icon: KeyPath<CompoundIcons, Image>, selectedIcon: KeyPath<CompoundIcons, Image>, isSearch: Bool = false) {
|
||||
init(tag: Tag, title: String, icon: KeyPath<CompoundIcons, Image>, selectedIcon: KeyPath<CompoundIcons, Image>, isSearch: Bool = false, accessibilityIdentifier: String? = nil) {
|
||||
self.tag = tag
|
||||
self.title = title
|
||||
self.icon = icon
|
||||
self.selectedIcon = selectedIcon
|
||||
self.isSearch = isSearch
|
||||
self.accessibilityIdentifier = accessibilityIdentifier
|
||||
}
|
||||
|
||||
func barVisibility(in horizontalSizeClass: UserInterfaceSizeClass?) -> Visibility {
|
||||
@@ -406,6 +408,7 @@ private struct NavigationTabCoordinatorView<Tag: Hashable>: View {
|
||||
}
|
||||
}
|
||||
.badge(module.details.badgeCount)
|
||||
.accessibilityIdentifier(module.details.accessibilityIdentifier ?? "")
|
||||
}
|
||||
}
|
||||
.backportTabBarMinimizeBehaviorOnScrollDown()
|
||||
|
||||
@@ -90,13 +90,13 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
let chatsSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator(hideBrandChrome: flowParameters.userSession.userSettings.app.hideBrandChrome))
|
||||
chatsTabFlowCoordinator = ChatsTabFlowCoordinator(navigationSplitCoordinator: chatsSplitCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
chatsTabDetails = .init(tag: HomeTab.chats, title: L10n.screenHomeTabChats, icon: \.chat, selectedIcon: \.chatSolid)
|
||||
chatsTabDetails = .init(tag: HomeTab.chats, title: L10n.screenHomeTabChats, icon: \.chat, selectedIcon: \.chatSolid, accessibilityIdentifier: A11yIdentifiers.homeTabs.chats)
|
||||
chatsTabDetails.navigationSplitCoordinator = chatsSplitCoordinator
|
||||
|
||||
let spacesSplitCoordinator = NavigationSplitCoordinator(placeholderCoordinator: PlaceholderScreenCoordinator(hideBrandChrome: flowParameters.userSession.userSettings.app.hideBrandChrome))
|
||||
spacesTabFlowCoordinator = SpacesTabFlowCoordinator(navigationSplitCoordinator: spacesSplitCoordinator,
|
||||
flowParameters: flowParameters)
|
||||
spacesTabDetails = .init(tag: HomeTab.spaces, title: L10n.screenHomeTabSpaces, icon: \.space, selectedIcon: \.spaceSolid)
|
||||
spacesTabDetails = .init(tag: HomeTab.spaces, title: L10n.screenHomeTabSpaces, icon: \.space, selectedIcon: \.spaceSolid, accessibilityIdentifier: A11yIdentifiers.homeTabs.spaces)
|
||||
spacesTabDetails.navigationSplitCoordinator = spacesSplitCoordinator
|
||||
|
||||
if flowParameters.userSession.userSettings.app.globalSearchEnabled {
|
||||
@@ -108,7 +108,7 @@ class UserSessionFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
searchScreenCoordinator = searchCoordinator
|
||||
searchTabNavigationStackCoordinator = searchStackCoordinator
|
||||
searchTabDetails = .init(tag: HomeTab.search, title: UntranslatedL10n.screenHomeTabSearch, icon: \.search, selectedIcon: \.search, isSearch: true)
|
||||
searchTabDetails = .init(tag: HomeTab.search, title: UntranslatedL10n.screenHomeTabSearch, icon: \.search, selectedIcon: \.search, isSearch: true, accessibilityIdentifier: A11yIdentifiers.homeTabs.search)
|
||||
} else {
|
||||
searchScreenCoordinator = nil
|
||||
searchTabNavigationStackCoordinator = nil
|
||||
|
||||
@@ -20,6 +20,7 @@ enum A11yIdentifiers {
|
||||
static let encryptionResetScreen = EncryptionResetScreen()
|
||||
static let encryptionResetPasswordScreen = EncryptionResetPasswordScreen()
|
||||
static let homeScreen = HomeScreen()
|
||||
static let homeTabs = HomeTabs()
|
||||
static let loginScreen = LoginScreen()
|
||||
static let authenticationStartScreen = AuthenticationStartScreen()
|
||||
static let reportContent = ReportContent()
|
||||
@@ -48,6 +49,7 @@ enum A11yIdentifiers {
|
||||
static let spacesScreen = SpacesScreen()
|
||||
static let spaceScreen = SpaceScreen()
|
||||
static let spaceAddRoomsScreen = SpaceAddRoomsScreen()
|
||||
static let searchScreen = SearchScreen()
|
||||
static let spaceSettingsScreen = SpaceSettingsScreen()
|
||||
static let linkNewDeviceScreen = LinkNewDeviceScreen()
|
||||
|
||||
@@ -120,6 +122,12 @@ enum A11yIdentifiers {
|
||||
}
|
||||
}
|
||||
|
||||
struct HomeTabs {
|
||||
let chats = "home_tabs-chats"
|
||||
let spaces = "home_tabs-spaces"
|
||||
let search = "home_tabs-search"
|
||||
}
|
||||
|
||||
struct InviteUsersScreen {
|
||||
let proceed = "invite_users-proceed"
|
||||
let userProfile = "invite_users-user_profile"
|
||||
@@ -353,6 +361,13 @@ enum A11yIdentifiers {
|
||||
let cancel = "space_add_rooms_screen-cancel"
|
||||
}
|
||||
|
||||
struct SearchScreen {
|
||||
let roomNamePrefix = "search_screen-room_name"
|
||||
func roomName(_ name: String) -> String {
|
||||
"\(roomNamePrefix):\(name)"
|
||||
}
|
||||
}
|
||||
|
||||
struct SpaceSettingsScreen {
|
||||
let editBaseInfo = "space_settings_screen-edit_space_info"
|
||||
}
|
||||
|
||||
@@ -283,7 +283,7 @@ struct SearchScreen: View {
|
||||
private extension View {
|
||||
/// Searchable makes the preview contents randomly appear lower
|
||||
@ViewBuilder func conditionalSearchable(searchQuery: Binding<String>) -> some View {
|
||||
if !ProcessInfo.isXcodePreview, !ProcessInfo.isRunningTests {
|
||||
if !ProcessInfo.isXcodePreview, !ProcessInfo.isRunningTests || ProcessInfo.isRunningIntegrationTests {
|
||||
searchable(text: searchQuery, placement: .toolbarPrincipal)
|
||||
} else {
|
||||
self
|
||||
@@ -334,6 +334,7 @@ private struct SearchScreenRoomCell: View {
|
||||
.padding(.vertical, 12)
|
||||
}
|
||||
.buttonStyle(SearchScreenRoomCellButtonStyle(isSelected: isSelected))
|
||||
.accessibilityIdentifier(A11yIdentifiers.searchScreen.roomName(room.title))
|
||||
.listRowInsets(.init())
|
||||
.listRowSeparator(.hidden)
|
||||
.rowDivider()
|
||||
|
||||
@@ -31,12 +31,17 @@ class UserFlowTests: XCTestCase {
|
||||
/// Assumes app is on the home screen
|
||||
private func checkRoomFlows() {
|
||||
// Search for the special test room
|
||||
let searchField = app.searchFields.firstMatch
|
||||
let searchTab = app.buttons[A11yIdentifiers.homeTabs.search].firstMatch
|
||||
XCTAssertTrue(searchTab.waitForExistence(timeout: 30))
|
||||
searchTab.tap(.center)
|
||||
|
||||
// The search tab hosts its field in the tab bar, which exposes it as a text field.
|
||||
let searchField = app.textFields.firstMatch
|
||||
XCTAssertTrue(searchField.waitForExistence(timeout: 30))
|
||||
searchField.clearAndTypeText(Self.integrationTestsRoomName, app: app)
|
||||
|
||||
// And open it
|
||||
let firstRoom = app.buttons.matching(NSPredicate(format: "identifier CONTAINS %@", Self.integrationTestsRoomName)).firstMatch
|
||||
let firstRoom = app.buttons[A11yIdentifiers.searchScreen.roomName(Self.integrationTestsRoomName)].firstMatch
|
||||
|
||||
// The backend is sometimes really slow and having a longer timeout
|
||||
// beats having to rerun the whole suite again.
|
||||
@@ -50,11 +55,6 @@ class UserFlowTests: XCTestCase {
|
||||
|
||||
// Go back to the room list
|
||||
tapOnBackButton("Chats")
|
||||
|
||||
// Cancel initial the room search
|
||||
let searchCancelButton = app.buttons["Close"].firstMatch
|
||||
XCTAssertTrue(searchCancelButton.waitForExistence(timeout: 10.0))
|
||||
searchCancelButton.tap(.center)
|
||||
}
|
||||
|
||||
private func sendMessages() {
|
||||
|
||||
@@ -197,7 +197,7 @@ class UserSessionScreenTests: XCTestCase {
|
||||
try await app.assertScreenshot(step: Step.homeScreenWithTabBar)
|
||||
|
||||
// app.tabBars doesn't work on iPadOS 18 😐
|
||||
app.buttons["Spaces"].firstMatch.tap(.center)
|
||||
app.buttons[A11yIdentifiers.homeTabs.spaces].firstMatch.tap(.center)
|
||||
|
||||
try await app.assertScreenshot(step: Step.spacesScreen)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user