Include the Members and Add Rooms screens in the spaces UI tests. (#4981)
* Expand the space flow UI tests to include the add rooms screen. Also fixes some failures in these tests due to the room/space title now being a button. * Expand the space flow UI tests to include the space members screen. * Reset AppSettings before running preview tests.
This commit is contained in:
@@ -203,3 +203,14 @@ private extension RoomHero {
|
|||||||
avatarUrl: memberProxy.avatarURL?.absoluteString)
|
avatarUrl: memberProxy.avatarURL?.absoluteString)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
extension Array where Element == JoinedRoomProxyProtocol {
|
||||||
|
static var mockRooms: [JoinedRoomProxyProtocol] {
|
||||||
|
[
|
||||||
|
JoinedRoomProxyMock(.init(id: "1", name: "Room Name", canonicalAlias: "#room-name:example.com")),
|
||||||
|
JoinedRoomProxyMock(.init(id: "2", name: "Room Name", canonicalAlias: "#room-name:example.com")),
|
||||||
|
JoinedRoomProxyMock(.init(id: "3", name: "Room Name", canonicalAlias: "#room-name:example.com"))
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -43,8 +43,11 @@ enum A11yIdentifiers {
|
|||||||
static let notificationSettingsEditScreen = NotificationSettingsEditScreen()
|
static let notificationSettingsEditScreen = NotificationSettingsEditScreen()
|
||||||
static let pollFormScreen = PollFormScreen()
|
static let pollFormScreen = PollFormScreen()
|
||||||
static let roomPollsHistoryScreen = RoomPollsHistoryScreen()
|
static let roomPollsHistoryScreen = RoomPollsHistoryScreen()
|
||||||
|
static let roomMembersListScreen = RoomMembersListScreen()
|
||||||
static let manageRoomMemberSheet = ManageRoomMemberSheet()
|
static let manageRoomMemberSheet = ManageRoomMemberSheet()
|
||||||
static let spacesScreen = SpacesScreen()
|
static let spacesScreen = SpacesScreen()
|
||||||
|
static let spaceScreen = SpaceScreen()
|
||||||
|
static let spaceAddRoomsScreen = SpaceAddRoomsScreen()
|
||||||
static let linkNewDeviceScreen = LinkNewDeviceScreen()
|
static let linkNewDeviceScreen = LinkNewDeviceScreen()
|
||||||
|
|
||||||
struct AlertInfo {
|
struct AlertInfo {
|
||||||
@@ -303,6 +306,10 @@ enum A11yIdentifiers {
|
|||||||
let loadMore = "room_polls_history_screen-load_more"
|
let loadMore = "room_polls_history_screen-load_more"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct RoomMembersListScreen {
|
||||||
|
let invite = "room_members_list_screen-invite"
|
||||||
|
}
|
||||||
|
|
||||||
struct ManageRoomMemberSheet {
|
struct ManageRoomMemberSheet {
|
||||||
let viewProfile = "manage_room_member_sheet-view_profile"
|
let viewProfile = "manage_room_member_sheet-view_profile"
|
||||||
}
|
}
|
||||||
@@ -316,6 +323,16 @@ enum A11yIdentifiers {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SpaceScreen {
|
||||||
|
let moreMenu = "space_screen-more_menu"
|
||||||
|
let addExistingRooms = "space_screen-add_existing_rooms"
|
||||||
|
let viewMembers = "space_screen-view_members"
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SpaceAddRoomsScreen {
|
||||||
|
let cancel = "space_add_rooms_screen-cancel"
|
||||||
|
}
|
||||||
|
|
||||||
struct LinkNewDeviceScreen {
|
struct LinkNewDeviceScreen {
|
||||||
let cancel = "link_new_device_screen-cancel"
|
let cancel = "link_new_device_screen-cancel"
|
||||||
let mobileDevice = "link_new_device_screen-mobile_device"
|
let mobileDevice = "link_new_device_screen-mobile_device"
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ struct RoomMembersListScreen: View {
|
|||||||
Button(L10n.actionInvite) {
|
Button(L10n.actionInvite) {
|
||||||
context.send(viewAction: .invite)
|
context.send(viewAction: .invite)
|
||||||
}
|
}
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.roomMembersListScreen.invite)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,10 +226,6 @@ struct RoomScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static func makeViewModels(canSendMessage: Bool = true, hasSuccessor: Bool = false) -> ViewModels {
|
static func makeViewModels(canSendMessage: Bool = true, hasSuccessor: Bool = false) -> ViewModels {
|
||||||
// TimelineItemBubbledStylerView sets enableKeyShareOnInvite to true which if run
|
|
||||||
// before these tests, ends up adding a banner to the snapshots.
|
|
||||||
AppSettings.resetAllSettings()
|
|
||||||
|
|
||||||
let roomProxyMock = JoinedRoomProxyMock(.init(id: "stable_id",
|
let roomProxyMock = JoinedRoomProxyMock(.init(id: "stable_id",
|
||||||
name: "Preview room",
|
name: "Preview room",
|
||||||
hasOngoingCall: true,
|
hasOngoingCall: true,
|
||||||
|
|||||||
@@ -115,6 +115,7 @@ struct SpaceAddRoomsScreen: View {
|
|||||||
ToolbarButton(role: .cancel) {
|
ToolbarButton(role: .cancel) {
|
||||||
context.send(viewAction: .cancel)
|
context.send(viewAction: .cancel)
|
||||||
}
|
}
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.spaceAddRoomsScreen.cancel)
|
||||||
}
|
}
|
||||||
|
|
||||||
ToolbarItem(placement: .confirmationAction) {
|
ToolbarItem(placement: .confirmationAction) {
|
||||||
@@ -186,11 +187,7 @@ struct SpaceAddRoomsScreen_Previews: PreviewProvider, TestablePreview {
|
|||||||
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceServiceRoom: SpaceServiceRoomMock(.init(isSpace: true))))
|
let spaceRoomListProxy = SpaceRoomListProxyMock(.init(spaceServiceRoom: SpaceServiceRoomMock(.init(isSpace: true))))
|
||||||
|
|
||||||
let clientProxy = ClientProxyMock(.init())
|
let clientProxy = ClientProxyMock(.init())
|
||||||
clientProxy.recentlyVisitedRoomsFilterReturnValue = [
|
clientProxy.recentlyVisitedRoomsFilterReturnValue = .mockRooms
|
||||||
JoinedRoomProxyMock(.init(id: "1", name: "Room Name", canonicalAlias: "#room-name:example.com")),
|
|
||||||
JoinedRoomProxyMock(.init(id: "2", name: "Room Name", canonicalAlias: "#room-name:example.com")),
|
|
||||||
JoinedRoomProxyMock(.init(id: "3", name: "Room Name", canonicalAlias: "#room-name:example.com"))
|
|
||||||
]
|
|
||||||
|
|
||||||
let viewModel = SpaceAddRoomsScreenViewModel(spaceRoomListProxy: spaceRoomListProxy,
|
let viewModel = SpaceAddRoomsScreenViewModel(spaceRoomListProxy: spaceRoomListProxy,
|
||||||
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
userSession: UserSessionMock(.init(clientProxy: clientProxy)),
|
||||||
|
|||||||
@@ -100,6 +100,8 @@ struct SpaceScreen: View {
|
|||||||
Button { context.send(viewAction: .addExistingRooms) } label: {
|
Button { context.send(viewAction: .addExistingRooms) } label: {
|
||||||
Label(L10n.actionAddExistingRooms, icon: \.room)
|
Label(L10n.actionAddExistingRooms, icon: \.room)
|
||||||
}
|
}
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.spaceScreen.addExistingRooms)
|
||||||
|
|
||||||
Button { context.send(viewAction: .manageChildren) } label: {
|
Button { context.send(viewAction: .manageChildren) } label: {
|
||||||
Label(L10n.actionManageRooms, icon: \.edit)
|
Label(L10n.actionManageRooms, icon: \.edit)
|
||||||
}
|
}
|
||||||
@@ -111,7 +113,9 @@ struct SpaceScreen: View {
|
|||||||
Button { context.send(viewAction: .displayMembers(roomProxy: roomProxy)) } label: {
|
Button { context.send(viewAction: .displayMembers(roomProxy: roomProxy)) } label: {
|
||||||
Label(L10n.screenSpaceMenuActionMembers, icon: \.user)
|
Label(L10n.screenSpaceMenuActionMembers, icon: \.user)
|
||||||
}
|
}
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.spaceScreen.viewMembers)
|
||||||
}
|
}
|
||||||
|
|
||||||
if let permalink = context.viewState.permalink {
|
if let permalink = context.viewState.permalink {
|
||||||
ShareLink(item: permalink) {
|
ShareLink(item: permalink) {
|
||||||
Label(L10n.actionShare, icon: \.shareIos)
|
Label(L10n.actionShare, icon: \.shareIos)
|
||||||
@@ -135,6 +139,7 @@ struct SpaceScreen: View {
|
|||||||
// Use an SF Symbol to match what ToolbarItemGroup(placement: .secondaryAction) would give us.
|
// Use an SF Symbol to match what ToolbarItemGroup(placement: .secondaryAction) would give us.
|
||||||
Image(systemSymbol: .ellipsis)
|
Image(systemSymbol: .ellipsis)
|
||||||
}
|
}
|
||||||
|
.accessibilityIdentifier(A11yIdentifiers.spaceScreen.moreMenu)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -596,8 +596,9 @@ class MockScreen: Identifiable {
|
|||||||
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com",
|
let clientProxy = ClientProxyMock(.init(userID: "@mock:client.com",
|
||||||
deviceID: "MOCKCLIENT",
|
deviceID: "MOCKCLIENT",
|
||||||
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(roomSummaries))),
|
roomSummaryProvider: RoomSummaryProviderMock(.init(state: .loaded(roomSummaries))),
|
||||||
spaceServiceConfiguration: .init(topLevelSpaces: .mockSingleRoom),
|
spaceServiceConfiguration: .init(topLevelSpaces: .mockSpaceList.filter(\.isSpace) + .mockSingleRoom),
|
||||||
roomPreviews: [SpaceServiceRoomProtocol].mockSpaceList.map(RoomPreviewProxyMock.init)))
|
roomPreviews: [SpaceServiceRoomProtocol].mockSpaceList.map(RoomPreviewProxyMock.init)))
|
||||||
|
clientProxy.recentlyVisitedRoomsFilterReturnValue = .mockRooms
|
||||||
|
|
||||||
// The tab bar remains hidden for the non-spaces tests as we don't supply any mock spaces.
|
// The tab bar remains hidden for the non-spaces tests as we don't supply any mock spaces.
|
||||||
let spaceServiceProxy = SpaceServiceProxyMock(id == .userSessionSpacesFlow ? .populated : .init())
|
let spaceServiceProxy = SpaceServiceProxyMock(id == .userSessionSpacesFlow ? .populated : .init())
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -27,6 +27,7 @@ extension PreviewTests {
|
|||||||
|
|
||||||
{% for type in types.types where (type.implements.TestablePreview or type.based.TestablePreview or type|annotated:"TestablePreview") and type.name != "TestablePreview" %}
|
{% for type in types.types where (type.implements.TestablePreview or type.based.TestablePreview or type|annotated:"TestablePreview") and type.name != "TestablePreview" %}
|
||||||
func test{{ type.name|replace:"_Previews", "" }}() async throws {
|
func test{{ type.name|replace:"_Previews", "" }}() async throws {
|
||||||
|
AppSettings.resetAllSettings() // Ensure this test's previews start with fresh settings.
|
||||||
for (index, preview) in {{ type.name }}._allPreviews.enumerated() {
|
for (index, preview) in {{ type.name }}._allPreviews.enumerated() {
|
||||||
try await assertSnapshots(matching: preview, step: index)
|
try await assertSnapshots(matching: preview, step: index)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
static let subspaceScreen = 7
|
static let subspaceScreen = 7
|
||||||
static let subspaceRoomScreen = 8
|
static let subspaceRoomScreen = 8
|
||||||
static let spaceJoinRoomScreen = 9
|
static let spaceJoinRoomScreen = 9
|
||||||
|
static let spaceAddRoomsScreen = 10
|
||||||
|
static let spaceMembersListScreen = 11
|
||||||
}
|
}
|
||||||
|
|
||||||
func testUserSessionFlows() async throws {
|
func testUserSessionFlows() async throws {
|
||||||
@@ -37,7 +39,7 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
try await app.assertScreenshot(step: Step.homeScreen)
|
try await app.assertScreenshot(step: Step.homeScreen)
|
||||||
|
|
||||||
app.buttons[A11yIdentifiers.homeScreen.roomName(firstRoomName)].tap()
|
app.buttons[A11yIdentifiers.homeScreen.roomName(firstRoomName)].tap()
|
||||||
XCTAssert(app.staticTexts[firstRoomName].waitForExistence(timeout: 5.0))
|
XCTAssert(app.buttons[firstRoomName].waitForExistence(timeout: 5.0))
|
||||||
try await Task.sleep(for: .seconds(1))
|
try await Task.sleep(for: .seconds(1))
|
||||||
try await app.assertScreenshot(step: Step.roomScreen)
|
try await app.assertScreenshot(step: Step.roomScreen)
|
||||||
|
|
||||||
@@ -48,7 +50,7 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
func testUserSessionReply() async throws {
|
func testUserSessionReply() async throws {
|
||||||
let app = Application.launch(.userSessionScreenReply, disableTimelineAccessibility: false)
|
let app = Application.launch(.userSessionScreenReply, disableTimelineAccessibility: false)
|
||||||
app.buttons[A11yIdentifiers.homeScreen.roomName(firstRoomName)].tap()
|
app.buttons[A11yIdentifiers.homeScreen.roomName(firstRoomName)].tap()
|
||||||
XCTAssert(app.staticTexts[firstRoomName].waitForExistence(timeout: 5.0))
|
XCTAssert(app.buttons[firstRoomName].waitForExistence(timeout: 5.0))
|
||||||
try await Task.sleep(for: .seconds(1))
|
try await Task.sleep(for: .seconds(1))
|
||||||
|
|
||||||
let cell = app.cells.element(boundBy: 1) // Skip the typing indicator cell
|
let cell = app.cells.element(boundBy: 1) // Skip the typing indicator cell
|
||||||
@@ -61,7 +63,7 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
let app = Application.launch(.userSessionScreen)
|
let app = Application.launch(.userSessionScreen)
|
||||||
|
|
||||||
app.buttons[A11yIdentifiers.homeScreen.roomName(firstRoomName)].tap()
|
app.buttons[A11yIdentifiers.homeScreen.roomName(firstRoomName)].tap()
|
||||||
XCTAssert(app.staticTexts[firstRoomName].waitForExistence(timeout: 5.0))
|
XCTAssert(app.buttons[firstRoomName].waitForExistence(timeout: 5.0))
|
||||||
|
|
||||||
app.buttons[A11yIdentifiers.roomScreen.joinCall].tap()
|
app.buttons[A11yIdentifiers.roomScreen.joinCall].tap()
|
||||||
|
|
||||||
@@ -94,8 +96,26 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
try await Task.sleep(for: .seconds(1))
|
try await Task.sleep(for: .seconds(1))
|
||||||
try await app.assertScreenshot(step: Step.subspaceScreen)
|
try await app.assertScreenshot(step: Step.subspaceScreen)
|
||||||
|
|
||||||
|
app.buttons[A11yIdentifiers.spaceScreen.moreMenu].tap()
|
||||||
|
app.buttons[A11yIdentifiers.spaceScreen.addExistingRooms].tap()
|
||||||
|
XCTAssert(app.buttons[A11yIdentifiers.spaceAddRoomsScreen.cancel].waitForExistence(timeout: 5.0))
|
||||||
|
try await Task.sleep(for: .seconds(1))
|
||||||
|
try await app.assertScreenshot(step: Step.spaceAddRoomsScreen)
|
||||||
|
|
||||||
|
app.buttons[A11yIdentifiers.spaceAddRoomsScreen.cancel].tap()
|
||||||
|
XCTAssert(app.staticTexts[joinedSubspaceName].waitForExistence(timeout: 5.0))
|
||||||
|
|
||||||
|
app.buttons[A11yIdentifiers.spaceScreen.moreMenu].tap()
|
||||||
|
app.buttons[A11yIdentifiers.spaceScreen.viewMembers].tap()
|
||||||
|
XCTAssert(app.buttons[A11yIdentifiers.roomMembersListScreen.invite].waitForExistence(timeout: 5.0))
|
||||||
|
try await Task.sleep(for: .seconds(1))
|
||||||
|
try await app.assertScreenshot(step: Step.spaceMembersListScreen)
|
||||||
|
|
||||||
|
app.navigationBars.buttons[joinedSubspaceName].firstMatch.tap(.center)
|
||||||
|
XCTAssert(app.staticTexts[joinedSubspaceName].waitForExistence(timeout: 5.0))
|
||||||
|
|
||||||
app.buttons[A11yIdentifiers.spacesScreen.spaceRoomName(joinedSubspaceRoomName)].tap()
|
app.buttons[A11yIdentifiers.spacesScreen.spaceRoomName(joinedSubspaceRoomName)].tap()
|
||||||
XCTAssert(app.staticTexts[joinedSubspaceRoomName].waitForExistence(timeout: 5.0))
|
XCTAssert(app.buttons[joinedSubspaceRoomName].waitForExistence(timeout: 5.0))
|
||||||
try await Task.sleep(for: .seconds(1))
|
try await Task.sleep(for: .seconds(1))
|
||||||
try await app.assertScreenshot(step: Step.subspaceRoomScreen)
|
try await app.assertScreenshot(step: Step.subspaceRoomScreen)
|
||||||
|
|
||||||
@@ -126,7 +146,7 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
|
|
||||||
// Tap join on the join room screen.
|
// Tap join on the join room screen.
|
||||||
app.buttons[A11yIdentifiers.joinRoomScreen.join].tap()
|
app.buttons[A11yIdentifiers.joinRoomScreen.join].tap()
|
||||||
XCTAssert(app.staticTexts[A11yIdentifiers.roomScreen.name].waitForExistence(timeout: 5.0)) // The space screen reuses the room screen header
|
XCTAssert(app.buttons[A11yIdentifiers.roomScreen.name].waitForExistence(timeout: 5.0)) // The space screen reuses the room screen header
|
||||||
try await Task.sleep(for: .seconds(1))
|
try await Task.sleep(for: .seconds(1))
|
||||||
try await app.assertScreenshot(step: Step.spaceScreen)
|
try await app.assertScreenshot(step: Step.spaceScreen)
|
||||||
|
|
||||||
@@ -144,7 +164,7 @@ class UserSessionScreenTests: XCTestCase {
|
|||||||
app.buttons.matching(NSPredicate(format: "identifier == %@ && label == %@",
|
app.buttons.matching(NSPredicate(format: "identifier == %@ && label == %@",
|
||||||
A11yIdentifiers.homeScreen.roomName(spaceInviteName),
|
A11yIdentifiers.homeScreen.roomName(spaceInviteName),
|
||||||
"Accept")).firstMatch.tap()
|
"Accept")).firstMatch.tap()
|
||||||
XCTAssert(app.staticTexts[A11yIdentifiers.roomScreen.name].waitForExistence(timeout: 5.0)) // The space screen reuses the room screen header
|
XCTAssert(app.buttons[A11yIdentifiers.roomScreen.name].waitForExistence(timeout: 5.0)) // The space screen reuses the room screen header
|
||||||
try await Task.sleep(for: .seconds(1))
|
try await Task.sleep(for: .seconds(1))
|
||||||
try await app.assertScreenshot(step: Step.spaceScreen)
|
try await app.assertScreenshot(step: Step.spaceScreen)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:67e8f04eb61e42989683d1d5e8667474928123902d4980a470b481589c84ac37
|
||||||
|
size 312442
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:06d692328ca4bd472d38dc907a22e3ca7400caac504493012a9cb950ffa6c711
|
||||||
|
size 331112
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:6361faefaeff3d18121fe975c6c472a5f33b08cd4818c6e6192dcf5c940ffeae
|
||||||
|
size 171619
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
version https://git-lfs.github.com/spec/v1
|
||||||
|
oid sha256:0f9e70f683eb594c733961f8263a492845adef03ac965ee6e8b2bb86b3e2adc7
|
||||||
|
size 229161
|
||||||
Reference in New Issue
Block a user