Accessibiliy Tests part 2 (#4325)

* running all the tests

* setting up CI

* fixed the workflow

* workflow on pull request, just to make it appear

* removed the test to run var

* fix archived tests name

* improved the tests, by filtering out some noise

* pr suggestions and added an improvement to the filtering

* improved the interrupt handler

* improved the UI interruption monitor handler

* some more refinement to handle the interruptor + false positive for non human readable labels

* reverted wrong commit

* ready for review, removed the on pull request check

* pr suggestions
This commit is contained in:
Mauro
2025-07-18 10:33:45 +02:00
committed by GitHub
parent 3cb815f7d4
commit a18eff9201
16 changed files with 1028 additions and 54 deletions

View File

@@ -0,0 +1,47 @@
name: Accessibility Tests
on:
workflow_dispatch:
schedule:
- cron: '0 2 * * 1-5'
jobs:
tests:
name: Tests
runs-on: macos-15
concurrency:
# Only allow a single run of this workflow on each branch, automatically cancelling older runs.
group: ${{ format('accessibility-tests-{0}', github.ref) }}
cancel-in-progress: true
steps:
- uses: nschloe/action-cached-lfs-checkout@f46300cd8952454b9f0a21a3d133d4bd5684cfc2 #v1.2.3
- uses: actions/cache@v4
with:
path: vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: Setup environment
run: source ci_scripts/ci_common.sh && setup_github_actions_environment
- name: Run tests
run: bundle exec fastlane accessibility_tests
- name: Zip results # for faster upload
if: failure()
working-directory: fastlane/test_output
run: zip -r AccessibilityTests.xcresult.zip AccessibilityTests.xcresult
- name: Archive artifacts
uses: actions/upload-artifact@v4
if: failure()
with:
name: Results
path: fastlane/test_output/AccessibilityTests.xcresult.zip
retention-days: 7
if-no-files-found: ignore

View File

@@ -0,0 +1,119 @@
//
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import XCTest
@MainActor
final class AccessibilityTests: XCTestCase {
var app: XCUIApplication!
func performAccessibilityAudit(named name: String) async throws {
let client = try UITestsSignalling.Client(mode: .tests)
app = Application.launch(viewID: name)
await client.waitForApp()
defer { try? client.stop() }
// To handle system interrupts
_ = addUIInterruptionMonitor(withDescription: "Location access alert handler") { alert in
let alwaysAllowButton = alert.buttons["Allow While Using App"]
if alwaysAllowButton.exists {
alwaysAllowButton.tap()
return true
}
return false
}
// This interaction is needed to have the UIInterruptionMonitor work properly.
app.tap()
try client.send(.accessibilityAudit(.nextPreview))
forLoop: for await signal in client.signals.values {
switch signal {
case .accessibilityAudit(let auditSignal):
switch auditSignal {
case .nextPreviewReady(let name):
performAccessibilityAuditForPreview(named: name)
try client.send(.accessibilityAudit(.nextPreview))
case .noMorePreviews:
break forLoop
default:
XCTFail("Unhandled signal")
}
default:
XCTFail("Unhandled signal")
}
}
app.terminate()
}
private func performAccessibilityAuditForPreview(named name: String) {
// Alows us to log the name of the preview that is being tested
XCTContext.runActivity(named: name) { _ in
do {
// We have removed `textClipped` and `contrast` for now
try app.performAccessibilityAudit(for: [.dynamicType, .elementDetection, .hitRegion, .sufficientElementDescription, .trait]) { issue in
// Remove false positives for null elements
guard let element = issue.element else {
return true
}
// We are fine with elements that only partially support dynamic types
guard issue.compactDescription != Self.partiallyUnsupportedDynamicTypeMessage else {
return true
}
// We can filter out matrix entities from the non human-readable error
if issue.compactDescription == Self.notHumanReadableMessage, Self.isMatrixIdentifier(element.label) {
return true
}
// Additional filters for specific elements that lead to false positives or neglectable issues.
if Self.ignoredA11yIdentifiers[element.identifier]?.isAccessibilityIssueFiltered(issue) == true {
return true
}
return false
}
} catch {
XCTFail("Failed to perform the accessibility audit: \(error)")
}
}
}
private static func isMatrixIdentifier(_ string: String) -> Bool {
MatrixEntityRegex.isMatrixRoomAlias(string) || MatrixEntityRegex.isMatrixUserIdentifier(string) || string == PillUtilities.atRoom
}
private static let partiallyUnsupportedDynamicTypeMessage = "Dynamic Type font sizes are partially unsupported"
private static let notHumanReadableMessage = "Label not human-readable"
/// Use this array to filter add specific filters to ignore specific issues for certain elements
private static let ignoredA11yIdentifiers: [String: [FilterType]] = [A11yIdentifiers.authenticationStartScreen.appVersion: [.auditType(.hitRegion)]]
}
private enum FilterType {
/// Filter by the content of the compactDescription of the issue
case compactDescription(String)
/// Filter by the type of the issue
case auditType(XCUIAccessibilityAuditType)
}
private extension Array where Element == FilterType {
func isAccessibilityIssueFiltered(_ issue: XCUIAccessibilityAuditIssue) -> Bool {
for filter in self {
switch filter {
case .auditType(issue.auditType):
return true
case .compactDescription(issue.compactDescription):
return true
default:
break
}
}
return false
}
}

View File

@@ -0,0 +1,768 @@
// Generated using Sourcery 2.2.7 https://github.com/krzysztofzablocki/Sourcery
// DO NOT EDIT
// swiftlint:disable all
// swiftformat:disable all
extension AccessibilityTests {
func testAdvancedSettingsScreen() async throws {
try await performAccessibilityAudit(named: "AdvancedSettingsScreen_Previews")
}
func testAnalyticsPromptScreen() async throws {
try await performAccessibilityAudit(named: "AnalyticsPromptScreen_Previews")
}
func testAnalyticsSettingsScreen() async throws {
try await performAccessibilityAudit(named: "AnalyticsSettingsScreen_Previews")
}
func testAppLockScreen() async throws {
try await performAccessibilityAudit(named: "AppLockScreen_Previews")
}
func testAppLockSetupBiometricsScreen() async throws {
try await performAccessibilityAudit(named: "AppLockSetupBiometricsScreen_Previews")
}
func testAppLockSetupPINScreen() async throws {
try await performAccessibilityAudit(named: "AppLockSetupPINScreen_Previews")
}
func testAppLockSetupSettingsScreen() async throws {
try await performAccessibilityAudit(named: "AppLockSetupSettingsScreen_Previews")
}
func testAudioMediaEventsTimelineView() async throws {
try await performAccessibilityAudit(named: "AudioMediaEventsTimelineView_Previews")
}
func testAudioRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "AudioRoomTimelineView_Previews")
}
func testAuthenticationStartScreen() async throws {
try await performAccessibilityAudit(named: "AuthenticationStartScreen_Previews")
}
func testAvatarHeaderView() async throws {
try await performAccessibilityAudit(named: "AvatarHeaderView_Previews")
}
func testBadgeLabel() async throws {
try await performAccessibilityAudit(named: "BadgeLabel_Previews")
}
func testBigIcon() async throws {
try await performAccessibilityAudit(named: "BigIcon_Previews")
}
func testBlockedUsersScreen() async throws {
try await performAccessibilityAudit(named: "BlockedUsersScreen_Previews")
}
func testBugReportScreen() async throws {
try await performAccessibilityAudit(named: "BugReportScreen_Previews")
}
func testCallInviteRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "CallInviteRoomTimelineView_Previews")
}
func testCallNotificationRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "CallNotificationRoomTimelineView_Previews")
}
func testCollapsibleRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "CollapsibleRoomTimelineView_Previews")
}
func testCompletionSuggestion() async throws {
try await performAccessibilityAudit(named: "CompletionSuggestion_Previews")
}
func testComposerToolbar() async throws {
try await performAccessibilityAudit(named: "ComposerToolbar_Previews")
}
func testCreateRoom() async throws {
try await performAccessibilityAudit(named: "CreateRoom_Previews")
}
func testDeactivateAccountScreen() async throws {
try await performAccessibilityAudit(named: "DeactivateAccountScreen_Previews")
}
func testDeclineAndBlockScreen() async throws {
try await performAccessibilityAudit(named: "DeclineAndBlockScreen_Previews")
}
func testEditRoomAddressScreen() async throws {
try await performAccessibilityAudit(named: "EditRoomAddressScreen_Previews")
}
func testElementTextFieldStyle() async throws {
try await performAccessibilityAudit(named: "ElementTextFieldStyle_Previews")
}
func testEmojiPickerScreenHeaderView() async throws {
try await performAccessibilityAudit(named: "EmojiPickerScreenHeaderView_Previews")
}
func testEmojiPickerScreen() async throws {
try await performAccessibilityAudit(named: "EmojiPickerScreen_Previews")
}
func testEmoteRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "EmoteRoomTimelineView_Previews")
}
func testEncryptedRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "EncryptedRoomTimelineView_Previews")
}
func testEncryptionResetPasswordScreen() async throws {
try await performAccessibilityAudit(named: "EncryptionResetPasswordScreen_Previews")
}
func testEncryptionResetScreen() async throws {
try await performAccessibilityAudit(named: "EncryptionResetScreen_Previews")
}
func testEstimatedWaveformView() async throws {
try await performAccessibilityAudit(named: "EstimatedWaveformView_Previews")
}
func testFileMediaEventsTimelineView() async throws {
try await performAccessibilityAudit(named: "FileMediaEventsTimelineView_Previews")
}
func testFileRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "FileRoomTimelineView_Previews")
}
func testFormButtonStyles() async throws {
try await performAccessibilityAudit(named: "FormButtonStyles_Previews")
}
func testFormattedBodyText() async throws {
try await performAccessibilityAudit(named: "FormattedBodyText_Previews")
}
func testFormattingToolbar() async throws {
try await performAccessibilityAudit(named: "FormattingToolbar_Previews")
}
func testFullscreenDialog() async throws {
try await performAccessibilityAudit(named: "FullscreenDialog_Previews")
}
func testGlobalSearchScreenListRow() async throws {
try await performAccessibilityAudit(named: "GlobalSearchScreenListRow_Previews")
}
func testGlobalSearchScreen() async throws {
try await performAccessibilityAudit(named: "GlobalSearchScreen_Previews")
}
func testHighlightedTimelineItemModifier() async throws {
try await performAccessibilityAudit(named: "HighlightedTimelineItemModifier_Previews")
}
func testHomeScreenEmptyStateView() async throws {
try await performAccessibilityAudit(named: "HomeScreenEmptyStateView_Previews")
}
func testHomeScreenInviteCell() async throws {
try await performAccessibilityAudit(named: "HomeScreenInviteCell_Previews")
}
func testHomeScreenKnockedCell() async throws {
try await performAccessibilityAudit(named: "HomeScreenKnockedCell_Previews")
}
func testHomeScreenRecoveryKeyConfirmationBanner() async throws {
try await performAccessibilityAudit(named: "HomeScreenRecoveryKeyConfirmationBanner_Previews")
}
func testHomeScreenRoomCell() async throws {
try await performAccessibilityAudit(named: "HomeScreenRoomCell_Previews")
}
func testHomeScreen() async throws {
try await performAccessibilityAudit(named: "HomeScreen_Previews")
}
func testIdentityConfirmationScreen() async throws {
try await performAccessibilityAudit(named: "IdentityConfirmationScreen_Previews")
}
func testIdentityConfirmedScreen() async throws {
try await performAccessibilityAudit(named: "IdentityConfirmedScreen_Previews")
}
func testImageMediaEventsTimelineView() async throws {
try await performAccessibilityAudit(named: "ImageMediaEventsTimelineView_Previews")
}
func testImageRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "ImageRoomTimelineView_Previews")
}
func testInviteUsersScreenSelectedItem() async throws {
try await performAccessibilityAudit(named: "InviteUsersScreenSelectedItem_Previews")
}
func testInviteUsersScreen() async throws {
try await performAccessibilityAudit(named: "InviteUsersScreen_Previews")
}
func testJoinRoomByAddressView() async throws {
try await performAccessibilityAudit(named: "JoinRoomByAddressView_Previews")
}
func testJoinRoomScreen() async throws {
try await performAccessibilityAudit(named: "JoinRoomScreen_Previews")
}
func testKnockRequestCell() async throws {
try await performAccessibilityAudit(named: "KnockRequestCell_Previews")
}
func testKnockRequestsBannerView() async throws {
try await performAccessibilityAudit(named: "KnockRequestsBannerView_Previews")
}
func testKnockRequestsListEmptyStateView() async throws {
try await performAccessibilityAudit(named: "KnockRequestsListEmptyStateView_Previews")
}
func testKnockRequestsListScreen() async throws {
try await performAccessibilityAudit(named: "KnockRequestsListScreen_Previews")
}
func testLegalInformationScreen() async throws {
try await performAccessibilityAudit(named: "LegalInformationScreen_Previews")
}
func testLoadableImage() async throws {
try await performAccessibilityAudit(named: "LoadableImage_Previews")
}
func testLocationMarkerView() async throws {
try await performAccessibilityAudit(named: "LocationMarkerView_Previews")
}
func testLocationRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "LocationRoomTimelineView_Previews")
}
func testLoginScreen() async throws {
try await performAccessibilityAudit(named: "LoginScreen_Previews")
}
func testLongPressWithFeedback() async throws {
try await performAccessibilityAudit(named: "LongPressWithFeedback_Previews")
}
func testManageRoomMemberSheetView() async throws {
try await performAccessibilityAudit(named: "ManageRoomMemberSheetView_Previews")
}
func testMapLibreStaticMapView() async throws {
try await performAccessibilityAudit(named: "MapLibreStaticMapView_Previews")
}
func testMatrixUserPermalink() async throws {
try await performAccessibilityAudit(named: "MatrixUserPermalink_Previews")
}
func testMediaEventsTimelineScreen() async throws {
try await performAccessibilityAudit(named: "MediaEventsTimelineScreen_Previews")
}
func testMediaUploadPreviewScreen() async throws {
try await performAccessibilityAudit(named: "MediaUploadPreviewScreen_Previews")
}
func testMentionSuggestionItemView() async throws {
try await performAccessibilityAudit(named: "MentionSuggestionItemView_Previews")
}
func testMessageComposerTextField() async throws {
try await performAccessibilityAudit(named: "MessageComposerTextField_Previews")
}
func testMessageComposer() async throws {
try await performAccessibilityAudit(named: "MessageComposer_Previews")
}
func testMessageForwardingScreen() async throws {
try await performAccessibilityAudit(named: "MessageForwardingScreen_Previews")
}
func testMessageText() async throws {
try await performAccessibilityAudit(named: "MessageText_Previews")
}
func testNoticeRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "NoticeRoomTimelineView_Previews")
}
func testNotificationPermissionsScreen() async throws {
try await performAccessibilityAudit(named: "NotificationPermissionsScreen_Previews")
}
func testNotificationSettingsEditScreenRoomCell() async throws {
try await performAccessibilityAudit(named: "NotificationSettingsEditScreenRoomCell_Previews")
}
func testNotificationSettingsEditScreen() async throws {
try await performAccessibilityAudit(named: "NotificationSettingsEditScreen_Previews")
}
func testNotificationSettingsScreen() async throws {
try await performAccessibilityAudit(named: "NotificationSettingsScreen_Previews")
}
func testPINTextField() async throws {
try await performAccessibilityAudit(named: "PINTextField_Previews")
}
func testPaginationIndicatorRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "PaginationIndicatorRoomTimelineView_Previews")
}
func testPillViewOnBubble() async throws {
try await performAccessibilityAudit(named: "PillViewOnBubble_Previews")
}
func testPillView() async throws {
try await performAccessibilityAudit(named: "PillView_Previews")
}
func testPinnedEventsTimelineScreen() async throws {
try await performAccessibilityAudit(named: "PinnedEventsTimelineScreen_Previews")
}
func testPinnedItemsBannerView() async throws {
try await performAccessibilityAudit(named: "PinnedItemsBannerView_Previews")
}
func testPinnedItemsIndicatorView() async throws {
try await performAccessibilityAudit(named: "PinnedItemsIndicatorView_Previews")
}
func testPlaceholderAvatarImage() async throws {
try await performAccessibilityAudit(named: "PlaceholderAvatarImage_Previews")
}
func testPlaceholderScreen() async throws {
try await performAccessibilityAudit(named: "PlaceholderScreen_Previews")
}
func testPollFormScreen() async throws {
try await performAccessibilityAudit(named: "PollFormScreen_Previews")
}
func testPollOptionView() async throws {
try await performAccessibilityAudit(named: "PollOptionView_Previews")
}
func testPollRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "PollRoomTimelineView_Previews")
}
func testPollView() async throws {
try await performAccessibilityAudit(named: "PollView_Previews")
}
func testQRCodeLoginScreen() async throws {
try await performAccessibilityAudit(named: "QRCodeLoginScreen_Previews")
}
func testReactionsSummaryView() async throws {
try await performAccessibilityAudit(named: "ReactionsSummaryView_Previews")
}
func testReadMarkerRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "ReadMarkerRoomTimelineView_Previews")
}
func testReadReceiptCell() async throws {
try await performAccessibilityAudit(named: "ReadReceiptCell_Previews")
}
func testReadReceiptsSummaryView() async throws {
try await performAccessibilityAudit(named: "ReadReceiptsSummaryView_Previews")
}
func testRedactedRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "RedactedRoomTimelineView_Previews")
}
func testReportContentScreen() async throws {
try await performAccessibilityAudit(named: "ReportContentScreen_Previews")
}
func testReportRoomScreen() async throws {
try await performAccessibilityAudit(named: "ReportRoomScreen_Previews")
}
func testResolveVerifiedUserSendFailureScreen() async throws {
try await performAccessibilityAudit(named: "ResolveVerifiedUserSendFailureScreen_Previews")
}
func testRoomAttachmentPicker() async throws {
try await performAccessibilityAudit(named: "RoomAttachmentPicker_Previews")
}
func testRoomAvatarImage() async throws {
try await performAccessibilityAudit(named: "RoomAvatarImage_Previews")
}
func testRoomChangePermissionsScreen() async throws {
try await performAccessibilityAudit(named: "RoomChangePermissionsScreen_Previews")
}
func testRoomChangeRolesScreenRow() async throws {
try await performAccessibilityAudit(named: "RoomChangeRolesScreenRow_Previews")
}
func testRoomChangeRolesScreenSelectedItem() async throws {
try await performAccessibilityAudit(named: "RoomChangeRolesScreenSelectedItem_Previews")
}
func testRoomChangeRolesScreen() async throws {
try await performAccessibilityAudit(named: "RoomChangeRolesScreen_Previews")
}
func testRoomDetailsEditScreen() async throws {
try await performAccessibilityAudit(named: "RoomDetailsEditScreen_Previews")
}
func testRoomDetailsScreen() async throws {
try await performAccessibilityAudit(named: "RoomDetailsScreen_Previews")
}
func testRoomDirectorySearchCell() async throws {
try await performAccessibilityAudit(named: "RoomDirectorySearchCell_Previews")
}
func testRoomDirectorySearchScreen() async throws {
try await performAccessibilityAudit(named: "RoomDirectorySearchScreen_Previews")
}
func testRoomHeaderView() async throws {
try await performAccessibilityAudit(named: "RoomHeaderView_Previews")
}
func testRoomInviterLabel() async throws {
try await performAccessibilityAudit(named: "RoomInviterLabel_Previews")
}
func testRoomListFilterView() async throws {
try await performAccessibilityAudit(named: "RoomListFilterView_Previews")
}
func testRoomListFiltersEmptyStateView() async throws {
try await performAccessibilityAudit(named: "RoomListFiltersEmptyStateView_Previews")
}
func testRoomListFiltersView() async throws {
try await performAccessibilityAudit(named: "RoomListFiltersView_Previews")
}
func testRoomMemberDetailsScreen() async throws {
try await performAccessibilityAudit(named: "RoomMemberDetailsScreen_Previews")
}
func testRoomMembersListMemberCell() async throws {
try await performAccessibilityAudit(named: "RoomMembersListMemberCell_Previews")
}
func testRoomMembersListScreen() async throws {
try await performAccessibilityAudit(named: "RoomMembersListScreen_Previews")
}
func testRoomNotificationSettingsCustomSectionView() async throws {
try await performAccessibilityAudit(named: "RoomNotificationSettingsCustomSectionView_Previews")
}
func testRoomNotificationSettingsScreen() async throws {
try await performAccessibilityAudit(named: "RoomNotificationSettingsScreen_Previews")
}
func testRoomNotificationSettingsUserDefinedScreen() async throws {
try await performAccessibilityAudit(named: "RoomNotificationSettingsUserDefinedScreen_Previews")
}
func testRoomPollsHistoryScreen() async throws {
try await performAccessibilityAudit(named: "RoomPollsHistoryScreen_Previews")
}
func testRoomRolesAndPermissionsScreen() async throws {
try await performAccessibilityAudit(named: "RoomRolesAndPermissionsScreen_Previews")
}
func testRoomScreenFooterView() async throws {
try await performAccessibilityAudit(named: "RoomScreenFooterView_Previews")
}
func testRoomScreen() async throws {
try await performAccessibilityAudit(named: "RoomScreen_Previews")
}
func testRoomSelectionScreen() async throws {
try await performAccessibilityAudit(named: "RoomSelectionScreen_Previews")
}
func testSFNumberedListView() async throws {
try await performAccessibilityAudit(named: "SFNumberedListView_Previews")
}
func testSecureBackupKeyBackupScreen() async throws {
try await performAccessibilityAudit(named: "SecureBackupKeyBackupScreen_Previews")
}
func testSecureBackupLogoutConfirmationScreen() async throws {
try await performAccessibilityAudit(named: "SecureBackupLogoutConfirmationScreen_Previews")
}
func testSecureBackupRecoveryKeyScreen() async throws {
try await performAccessibilityAudit(named: "SecureBackupRecoveryKeyScreen_Previews")
}
func testSecureBackupScreen() async throws {
try await performAccessibilityAudit(named: "SecureBackupScreen_Previews")
}
func testSecurityAndPrivacyScreen() async throws {
try await performAccessibilityAudit(named: "SecurityAndPrivacyScreen_Previews")
}
func testSendInviteConfirmationView() async throws {
try await performAccessibilityAudit(named: "SendInviteConfirmationView_Previews")
}
func testSeparatorMediaEventsTimelineView() async throws {
try await performAccessibilityAudit(named: "SeparatorMediaEventsTimelineView_Previews")
}
func testSeparatorRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "SeparatorRoomTimelineView_Previews")
}
func testServerConfirmationScreen() async throws {
try await performAccessibilityAudit(named: "ServerConfirmationScreen_Previews")
}
func testServerSelection() async throws {
try await performAccessibilityAudit(named: "ServerSelection_Previews")
}
func testSessionVerificationRequestDetailsView() async throws {
try await performAccessibilityAudit(named: "SessionVerificationRequestDetailsView_Previews")
}
func testSessionVerification() async throws {
try await performAccessibilityAudit(named: "SessionVerification_Previews")
}
func testSettingsScreen() async throws {
try await performAccessibilityAudit(named: "SettingsScreen_Previews")
}
func testShimmerOverlay() async throws {
try await performAccessibilityAudit(named: "ShimmerOverlay_Previews")
}
func testSoftLogoutScreen() async throws {
try await performAccessibilityAudit(named: "SoftLogoutScreen_Previews")
}
func testSplashScreen() async throws {
try await performAccessibilityAudit(named: "SplashScreen_Previews")
}
func testStackedAvatarsView() async throws {
try await performAccessibilityAudit(named: "StackedAvatarsView_Previews")
}
func testStartChatScreen() async throws {
try await performAccessibilityAudit(named: "StartChatScreen_Previews")
}
func testStateRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "StateRoomTimelineView_Previews")
}
func testStaticLocationScreenViewer() async throws {
try await performAccessibilityAudit(named: "StaticLocationScreenViewer_Previews")
}
func testStickerRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "StickerRoomTimelineView_Previews")
}
func testSwipeRightAction() async throws {
try await performAccessibilityAudit(named: "SwipeRightAction_Previews")
}
func testSwipeToReplyView() async throws {
try await performAccessibilityAudit(named: "SwipeToReplyView_Previews")
}
func testTextRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "TextRoomTimelineView_Previews")
}
func testThreadDecorator() async throws {
try await performAccessibilityAudit(named: "ThreadDecorator_Previews")
}
func testTimelineDeliveryStatusView() async throws {
try await performAccessibilityAudit(named: "TimelineDeliveryStatusView_Previews")
}
func testTimelineItemBubbledStylerView() async throws {
try await performAccessibilityAudit(named: "TimelineItemBubbledStylerView_Previews")
}
func testTimelineItemDebugView() async throws {
try await performAccessibilityAudit(named: "TimelineItemDebugView_Previews")
}
func testTimelineItemMenu() async throws {
try await performAccessibilityAudit(named: "TimelineItemMenu_Previews")
}
func testTimelineItemSendInfoLabel() async throws {
try await performAccessibilityAudit(named: "TimelineItemSendInfoLabel_Previews")
}
func testTimelineItemStyler() async throws {
try await performAccessibilityAudit(named: "TimelineItemStyler_Previews")
}
func testTimelineMediaPreviewDetailsView() async throws {
try await performAccessibilityAudit(named: "TimelineMediaPreviewDetailsView_Previews")
}
func testTimelineMediaPreviewRedactConfirmationView() async throws {
try await performAccessibilityAudit(named: "TimelineMediaPreviewRedactConfirmationView_Previews")
}
func testTimelineReactionView() async throws {
try await performAccessibilityAudit(named: "TimelineReactionView_Previews")
}
func testTimelineReadReceiptsView() async throws {
try await performAccessibilityAudit(named: "TimelineReadReceiptsView_Previews")
}
func testTimelineReplyView() async throws {
try await performAccessibilityAudit(named: "TimelineReplyView_Previews")
}
func testTimelineStartRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "TimelineStartRoomTimelineView_Previews")
}
func testTimelineThreadSummaryView() async throws {
try await performAccessibilityAudit(named: "TimelineThreadSummaryView_Previews")
}
func testTimelineView() async throws {
try await performAccessibilityAudit(named: "TimelineView_Previews")
}
func testTombstonedAvatarImage() async throws {
try await performAccessibilityAudit(named: "TombstonedAvatarImage_Previews")
}
func testTypingIndicatorView() async throws {
try await performAccessibilityAudit(named: "TypingIndicatorView_Previews")
}
func testUnsupportedRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "UnsupportedRoomTimelineView_Previews")
}
func testUserDetailsEditScreen() async throws {
try await performAccessibilityAudit(named: "UserDetailsEditScreen_Previews")
}
func testUserIndicatorModalView() async throws {
try await performAccessibilityAudit(named: "UserIndicatorModalView_Previews")
}
func testUserIndicatorToastView() async throws {
try await performAccessibilityAudit(named: "UserIndicatorToastView_Previews")
}
func testUserProfileCell() async throws {
try await performAccessibilityAudit(named: "UserProfileCell_Previews")
}
func testUserProfileScreen() async throws {
try await performAccessibilityAudit(named: "UserProfileScreen_Previews")
}
func testVerificationBadge() async throws {
try await performAccessibilityAudit(named: "VerificationBadge_Previews")
}
func testVideoMediaEventsTimelineView() async throws {
try await performAccessibilityAudit(named: "VideoMediaEventsTimelineView_Previews")
}
func testVideoRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "VideoRoomTimelineView_Previews")
}
func testVisualListItem() async throws {
try await performAccessibilityAudit(named: "VisualListItem_Previews")
}
func testVoiceMessageButton() async throws {
try await performAccessibilityAudit(named: "VoiceMessageButton_Previews")
}
func testVoiceMessageMediaEventsTimelineView() async throws {
try await performAccessibilityAudit(named: "VoiceMessageMediaEventsTimelineView_Previews")
}
func testVoiceMessagePreviewComposer() async throws {
try await performAccessibilityAudit(named: "VoiceMessagePreviewComposer_Previews")
}
func testVoiceMessageRecordingButton() async throws {
try await performAccessibilityAudit(named: "VoiceMessageRecordingButton_Previews")
}
func testVoiceMessageRecordingComposer() async throws {
try await performAccessibilityAudit(named: "VoiceMessageRecordingComposer_Previews")
}
func testVoiceMessageRecordingView() async throws {
try await performAccessibilityAudit(named: "VoiceMessageRecordingView_Previews")
}
func testVoiceMessageRoomPlaybackView() async throws {
try await performAccessibilityAudit(named: "VoiceMessageRoomPlaybackView_Previews")
}
func testVoiceMessageRoomTimelineView() async throws {
try await performAccessibilityAudit(named: "VoiceMessageRoomTimelineView_Previews")
}
func testWaveformCursorView() async throws {
try await performAccessibilityAudit(named: "WaveformCursorView_Previews")
}
}
// swiftlint:enable all
// swiftformat:enable all

View File

@@ -1,43 +0,0 @@
//
// Copyright 2025 New Vector Ltd.
//
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
// Please see LICENSE files in the repository root for full details.
//
import XCTest
@MainActor
class Test: XCTestCase {
var app: XCUIApplication!
func test() async throws {
let client = try UITestsSignalling.Client(mode: .tests)
app = Application.launch(viewID: "SecureBackupLogoutConfirmationScreen_Previews")
await client.waitForApp()
defer { try? client.stop() }
try client.send(.accessibilityAudit(.nextPreview))
forLoop: for await signal in client.signals.values {
switch signal {
case .accessibilityAudit(let auditSignal):
switch auditSignal {
case .nextPreviewReady(let name):
try? app.performAccessibilityAudit { issue in
XCTFail("\(name): \(issue)")
return true
}
try? client.send(.accessibilityAudit(.nextPreview))
case .noMorePreviews:
break forLoop
default:
fatalError("Unhandled signal")
}
default:
fatalError("Unhandled signal")
}
}
app.terminate()
}
}

View File

@@ -48,4 +48,8 @@ targets:
- path: ../Sources
- path: ../SupportingFiles
- path: ../../ElementX/Sources/UITests/UITestsSignalling.swift
- path: ../../ElementX/Sources/Other/AccessibilityIdentifiers.swift
- path: ../../ElementX/Sources/Other/MatrixEntityRegex.swift
- path: ../../ElementX/Sources/Other/Pills/PillUtilities.swift
- path: ../../ElementX/Sources/Other/Extensions/NSRegularExpresion.swift

View File

@@ -503,6 +503,7 @@
60ED66E63A169E47489348A8 /* Sentry in Frameworks */ = {isa = PBXBuildFile; productRef = 886A0A498FA01E8EDD451D05 /* Sentry */; };
611BEE29B8B622204E1E6B04 /* SecurityAndPrivacyScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 97F2F6B6E56055EF173A2DD3 /* SecurityAndPrivacyScreenCoordinator.swift */; };
617624A97BDBB75ED3DD8156 /* RoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = A00C7A331B72C0F05C00392F /* RoomScreenViewModelProtocol.swift */; };
6183BD3916CAA7134B6070D2 /* MatrixEntityRegex.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6AD1A853D605C2146B0DC028 /* MatrixEntityRegex.swift */; };
6189B4ABD535CE526FA1107B /* StartChatViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6DF438EAFC732D2D95D34BF6 /* StartChatViewModelTests.swift */; };
61941DEE5F3834765770BE01 /* InviteUsersScreenSelectedItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 10F32E0B4B83D2A11EE8D011 /* InviteUsersScreenSelectedItem.swift */; };
61A36B9BB2ADE36CEFF5E98C /* Array.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3E93A1BE7D8A2EBCAD51EEB4 /* Array.swift */; };
@@ -644,6 +645,7 @@
7B66DA4E7E5FE4D1A0FCEAA4 /* JoinRoomScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = EEAB5662310AE73D93815134 /* JoinRoomScreenViewModelProtocol.swift */; };
7BB31E67648CF32D2AB5E502 /* RoomScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9CE3C90E487B255B735D73C8 /* RoomScreenViewModel.swift */; };
7BD2123144A32F082CECC108 /* AudioRoomTimelineView.swift in Sources */ = {isa = PBXBuildFile; fileRef = B2EAFFD44F81F86012D6EC27 /* AudioRoomTimelineView.swift */; };
7BDC3976D88D40D2A45BEB8C /* NSRegularExpresion.swift in Sources */ = {isa = PBXBuildFile; fileRef = 95BAC0F6C9644336E9567EE6 /* NSRegularExpresion.swift */; };
7BF368A78E6D9AFD222F25AF /* SecureBackupScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AE094FCB6387D268C436161 /* SecureBackupScreenViewModel.swift */; };
7C0E29E0279866C62EC67A28 /* JoinRoomScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE5127D6EA05B2E45D0A7D59 /* JoinRoomScreenViewModelTests.swift */; };
7C164A642E8932B5F9004550 /* test_voice_message.m4a in Resources */ = {isa = PBXBuildFile; fileRef = DCA2D836BD10303F37FAAEED /* test_voice_message.m4a */; };
@@ -734,6 +736,7 @@
8B41D0357B91CD3B6F6A3BCA /* EmoteRoomTimelineItemContent.swift in Sources */ = {isa = PBXBuildFile; fileRef = EE378083653EF0C9B5E9D580 /* EmoteRoomTimelineItemContent.swift */; };
8B76191B9DDD1AC90A6E3A35 /* MediaFileHandleProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = DEC1D382565A4E9CAC2F14EA /* MediaFileHandleProxy.swift */; };
8BC8EF6705A78946C1F22891 /* SoftLogoutScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 71A7D4DDEEE5D2CA0C8D63CD /* SoftLogoutScreen.swift */; };
8BD22815DC34D7F9E9C1F2FE /* PillUtilities.swift in Sources */ = {isa = PBXBuildFile; fileRef = C537DE821FED94D23467B6C4 /* PillUtilities.swift */; };
8C050A8012E6078BEAEF5BC8 /* PillTextAttachmentData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 913C8E13B8B602C7B6C0C4AE /* PillTextAttachmentData.swift */; };
8C1A5ECAF895D4CAF8C4D461 /* AppActivityView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8F21ED7205048668BEB44A38 /* AppActivityView.swift */; };
8C706DA7EAC0974CA2F8F1CD /* MentionBuilder.swift in Sources */ = {isa = PBXBuildFile; fileRef = 15748C254911E3654C93B0ED /* MentionBuilder.swift */; };
@@ -847,7 +850,6 @@
A1672EF491FE6F3BBF7878BE /* test_apple_image.heic in Resources */ = {isa = PBXBuildFile; fileRef = BB576F4118C35E6B5124FA22 /* test_apple_image.heic */; };
A17FAD2EBC53E17B5FD384DB /* InviteUsersScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 22730A30C50AC2E3D5BA8642 /* InviteUsersScreenViewModelProtocol.swift */; };
A1BA8D6BABAFA9BAAEAA3FFD /* NotificationSettingsProxyProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4FDD775CFD72DD2D3C8A8390 /* NotificationSettingsProxyProtocol.swift */; };
A1C8951A632AC5F350FE0A6C /* Test.swift in Sources */ = {isa = PBXBuildFile; fileRef = 932E4E8BB476283CBF219427 /* Test.swift */; };
A1DF0E1E526A981ED6D5DF44 /* UserIndicatorControllerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2429224EB0EEA34D35CE9249 /* UserIndicatorControllerTests.swift */; };
A216C83ADCF32BA5EF8A6FBC /* InviteUsersViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 845DDBDE5A0887E73D38B826 /* InviteUsersViewModelTests.swift */; };
A2172B5A26976F9174228B8A /* AppHooks.swift in Sources */ = {isa = PBXBuildFile; fileRef = B6E4AB573FAEBB7B853DD04C /* AppHooks.swift */; };
@@ -991,6 +993,7 @@
BDA68E8D95B2B24B28825B8B /* LoginScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3C368CAB3063EF275357ECD4 /* LoginScreenViewModel.swift */; };
BDC4EB54CC3036730475CB8B /* QRCodeLoginScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 25E7E9B7FEAB6169D960C206 /* QRCodeLoginScreenViewModelTests.swift */; };
BDED6DA7AD1E76018C424143 /* LegalInformationScreenViewModel.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0C34667458773B02AB5FB0B2 /* LegalInformationScreenViewModel.swift */; };
BDFF0AEBF57B5B124062DAEF /* GeneratedAccessibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */; };
BE8E5985771DF9137C6CE89A /* ProcessInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = 077B01C13BBA2996272C5FB5 /* ProcessInfo.swift */; };
BEC6DFEA506085D3027E353C /* MediaEventsTimelineScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 002399C6CB875C4EBB01CBC0 /* MediaEventsTimelineScreen.swift */; };
BED59052E5C5163D2B065CA6 /* EventTimelineItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0A81FD0C60175FA081EB19AD /* EventTimelineItem.swift */; };
@@ -1041,6 +1044,7 @@
C85C7A201E4CFDA477ACEBEB /* AppLockSetupSettingsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8610C1D21565C950BCA6A454 /* AppLockSetupSettingsScreenViewModelProtocol.swift */; };
C8A9C595038AFA2D707AC8C1 /* NotificationPermissionsScreenViewModelProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 20E69F67D2A70ABD08CA6D54 /* NotificationPermissionsScreenViewModelProtocol.swift */; };
C8BD80891BAD688EF2C15CDB /* MediaUploadPreviewScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74DD0855F2F76D47E5555082 /* MediaUploadPreviewScreenCoordinator.swift */; };
C8D1D18E22672D48C11A5366 /* AccessibilityIdentifiers.swift in Sources */ = {isa = PBXBuildFile; fileRef = 04BB8DDE245ED86C489BA983 /* AccessibilityIdentifiers.swift */; };
C8E0FA0FF2CD6613264FA6B9 /* MessageForwardingScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = BFEA446F8618DBA79A9239CC /* MessageForwardingScreen.swift */; };
C8E1E4E06B7C7A3A8246FC9B /* MediaEventsTimelineScreenCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 8512B82404B1751D0BCC82D2 /* MediaEventsTimelineScreenCoordinator.swift */; };
C915347779B3C7FDD073A87A /* AVMetadataMachineReadableCodeObjectExtensionsTest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 93E1FF0DFBB3768F79FDBF6D /* AVMetadataMachineReadableCodeObjectExtensionsTest.swift */; };
@@ -1211,6 +1215,7 @@
ED635D7F00FA07E94D3CE1E8 /* PreviewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9B796D347E53631576F631C /* PreviewTests.swift */; };
ED90A59F068FD0CA27E602ED /* UserProfileListRow.swift in Sources */ = {isa = PBXBuildFile; fileRef = E10DA51DBC8C7E1460DBCCBD /* UserProfileListRow.swift */; };
EDB6915EC953BB2A44AA608E /* EditRoomAddressScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 906451FB8CF27C628152BF7A /* EditRoomAddressScreenViewModelTests.swift */; };
EDD45A73B688B87D84B9C2E9 /* AccessibilityTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7A6D867A7FBB70C6EFDBCBC5 /* AccessibilityTests.swift */; };
EDF8919F15DE0FF00EF99E70 /* DocumentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0F5567A7EF6F2AB9473236F6 /* DocumentPicker.swift */; };
EE4E2C1922BBF5169E213555 /* PillAttachmentViewProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 1B53D6C5C0D14B04D3AB3F6E /* PillAttachmentViewProvider.swift */; };
EE56238683BC3ECA9BA00684 /* GlobalSearchScreenViewModelTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = EA4D639E27D5882A6A71AECF /* GlobalSearchScreenViewModelTests.swift */; };
@@ -1989,6 +1994,7 @@
796CBD0C56FA0D3AEDAB255B /* SessionVerificationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SessionVerificationScreenCoordinator.swift; sourceTree = "<group>"; };
79A106D76741914F82664959 /* StateStoreViewModelV2.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StateStoreViewModelV2.swift; sourceTree = "<group>"; };
7A03E073077D92AA19C43DCF /* IdentityConfirmationScreenCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IdentityConfirmationScreenCoordinator.swift; sourceTree = "<group>"; };
7A6D867A7FBB70C6EFDBCBC5 /* AccessibilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccessibilityTests.swift; sourceTree = "<group>"; };
7AAD8C633AA57948B34EDCF7 /* RoomChangeRolesScreenViewModelProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RoomChangeRolesScreenViewModelProtocol.swift; sourceTree = "<group>"; };
7AC0CD1CAFD3F8B057F9AEA5 /* ClientBuilderHook.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ClientBuilderHook.swift; sourceTree = "<group>"; };
7AC1E3FE9B59EA094867863E /* TimelineControllerFactoryProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineControllerFactoryProtocol.swift; sourceTree = "<group>"; };
@@ -2122,7 +2128,6 @@
922E498EB74CF6F5CC236F81 /* AdvancedSettingsScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AdvancedSettingsScreenModels.swift; sourceTree = "<group>"; };
92390F9FA98255440A6BF5F8 /* OIDCAuthenticationPresenter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OIDCAuthenticationPresenter.swift; sourceTree = "<group>"; };
92DB574F954CC2B40F7BE892 /* QRCodeScannerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeScannerView.swift; sourceTree = "<group>"; };
932E4E8BB476283CBF219427 /* Test.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Test.swift; sourceTree = "<group>"; };
9332DFE9642F0A46ECA0497B /* BlurHashEncode.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BlurHashEncode.swift; sourceTree = "<group>"; };
933B074F006F8E930DB98B4E /* TimelineMediaFrame.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TimelineMediaFrame.swift; sourceTree = "<group>"; };
9342F5D6729627B6393AF853 /* ServerConfirmationScreenModels.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ServerConfirmationScreenModels.swift; sourceTree = "<group>"; };
@@ -2620,6 +2625,7 @@
F409D44C2E6BE50462E82F8A /* en-US */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "en-US"; path = "en-US.lproj/Localizable.strings"; sourceTree = "<group>"; };
F4469F6AE311BDC439B3A5EC /* UserSessionMock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserSessionMock.swift; sourceTree = "<group>"; };
F4548A9BDE5CB3AB864BCA9F /* EffectsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EffectsView.swift; sourceTree = "<group>"; };
F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GeneratedAccessibilityTests.swift; sourceTree = "<group>"; };
F506C6ADB1E1DA6638078E11 /* UITests.xctest */ = {isa = PBXFileReference; includeInIndex = 0; lastKnownFileType = wrapper.cfbundle; path = UITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
F51D674A5B5F1FE1B878E20F /* nb */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = nb; path = nb.lproj/Localizable.strings; sourceTree = "<group>"; };
F5311C989EC15B4C2D699025 /* StaticLocationScreenViewModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StaticLocationScreenViewModel.swift; sourceTree = "<group>"; };
@@ -6040,8 +6046,9 @@
EB9C851423AA9BC8CEC381DC /* Sources */ = {
isa = PBXGroup;
children = (
7A6D867A7FBB70C6EFDBCBC5 /* AccessibilityTests.swift */,
2D9DBE1C69F3A60D93B2203F /* Application.swift */,
932E4E8BB476283CBF219427 /* Test.swift */,
F4CEB4590CCF70F0E3C0B171 /* GeneratedAccessibilityTests.swift */,
);
path = Sources;
sourceTree = "<group>";
@@ -6861,7 +6868,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which sourcery >/dev/null; then\n sourcery --config Tools/Sourcery/TestablePreviewsDictionary.yml\nelse\n echo \"warning: Sourcery not installed, run swift run tools setup-project\"\nfi\n";
shellScript = "export PATH=\"$PATH:/opt/homebrew/bin\"\nif which sourcery >/dev/null; then\n sourcery --config Tools/Sourcery/TestablePreviewsDictionary.yml\n sourcery --config Tools/Sourcery/AccessibilityTests.yml\nelse\n echo \"warning: Sourcery not installed, run swift run tools setup-project\"\nfi\n";
};
/* End PBXShellScriptBuildPhase section */
@@ -7116,8 +7123,13 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
C8D1D18E22672D48C11A5366 /* AccessibilityIdentifiers.swift in Sources */,
EDD45A73B688B87D84B9C2E9 /* AccessibilityTests.swift in Sources */,
F996259EAE68664BC345C197 /* Application.swift in Sources */,
A1C8951A632AC5F350FE0A6C /* Test.swift in Sources */,
BDFF0AEBF57B5B124062DAEF /* GeneratedAccessibilityTests.swift in Sources */,
6183BD3916CAA7134B6070D2 /* MatrixEntityRegex.swift in Sources */,
7BDC3976D88D40D2A45BEB8C /* NSRegularExpresion.swift in Sources */,
8BD22815DC34D7F9E9C1F2FE /* PillUtilities.swift in Sources */,
E323A54F317604BDD6968D79 /* UITestsSignalling.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;

View File

@@ -6,6 +6,7 @@
//
import Combine
import CoreLocation
import SwiftUI
class AccessibilityTestsAppCoordinator: AppCoordinatorProtocol {
@@ -53,6 +54,8 @@ class AccessibilityTestsAppCoordinator: AppCoordinatorProtocol {
previewsWrapper = .init(name: name, previews: previewType._allPreviews)
setupSignalling()
// Used to perform the request check before the tests run on CI, so it can be immediately dismissed.
CLLocationManager().requestWhenInUseAuthorization()
}
func toPresentable() -> AnyView {
@@ -143,7 +146,12 @@ struct PreviewsWrapperView: View {
switch fulfillmentSource {
case .publisher(let publisher):
_ = await publisher.values.first { $0 == true }
_ = await publisher
// Not sure whye byt some publisher seem to not properly comunicate their completion,
// so we added a timeout. Since we are going to migrate from publishers to stream,
// this is a temporary solution
.timeout(.seconds(1), scheduler: DispatchQueue.main)
.values.first { $0 == true }
case .stream(let stream):
_ = await stream.first { $0 == true }
case .none:

View File

@@ -6,7 +6,6 @@
//
import Foundation
import MatrixRustSDK
// https://spec.matrix.org/latest/appendices/#identifier-grammar
enum MatrixEntityRegex: String {

View File

@@ -9,9 +9,6 @@ import Foundation
enum PillUtilities {
static let atRoom = "@room"
static var everyone: String {
L10n.commonEveryone
}
/// Used by the WYSIWYG as the urlString value to identify @room mentions
static let composerAtRoomURLString = "#"

View File

@@ -21,6 +21,9 @@ struct RoomHeaderView: View {
// https://github.com/element-hq/element-x-ios/issues/4180
// Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'NSLayoutConstraint constant is not finite!
content
} else if ProcessInfo.isRunningAccessibilityTests {
// Accessibility tests scale up the dynamic size in real time which may break the view
content
} else {
content
// Take up as much space as possible, with a leading alignment for use in the principal toolbar position

View File

@@ -168,3 +168,9 @@ final class CompletionSuggestionService: CompletionSuggestionServiceProtocol {
return roomName.localizedStandardContains(searchText) || roomAlias.localizedStandardContains(searchText)
}
}
extension PillUtilities {
static var everyone: String {
L10n.commonEveryone
}
}

View File

@@ -124,7 +124,8 @@ struct RoomScreen: View {
private var composer: some View {
if context.viewState.hasSuccessor {
tombstonedDialogue
} else if context.viewState.canSendMessage {
} else if context.viewState.canSendMessage, !ProcessInfo.isRunningAccessibilityTests {
// We are not sure why but when wrapped in the room screen the composer toolbar breaks the accessibility tests
composerToolbar
} else {
ComposerDisabledView()

View File

@@ -189,6 +189,7 @@ targets:
export PATH="$PATH:/opt/homebrew/bin"
if which sourcery >/dev/null; then
sourcery --config Tools/Sourcery/TestablePreviewsDictionary.yml
sourcery --config Tools/Sourcery/AccessibilityTests.yml
else
echo "warning: Sourcery not installed, run swift run tools setup-project"
fi

View File

@@ -0,0 +1,31 @@
// swiftlint:disable all
// swiftformat:disable all
{% if argument.mainTarget %}
@testable import {{ argument.mainTarget }}
{% endif %}
{% for import in argument.imports %}
{% if import != "last" %}
import {{ import }}
{% endif %}
{% endfor %}
{% for import in argument.testableImports %}
{% if import != "last" %}
@testable import {{ import }}
{% endif %}
{% endfor %}
extension AccessibilityTests {
{% 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 {
try await performAccessibilityAudit(named: "{{ type.name }}")
}
{%- if not forloop.last %}
{% endif %}
{% endfor %}
}
// swiftlint:enable all
// swiftformat:enable all

View File

@@ -0,0 +1,7 @@
sources:
include:
- ../../ElementX
templates:
- AccessibilityTests.stencil
output:
../../AccessibilityTests/Sources/GeneratedAccessibilityTests.swift

View File

@@ -85,6 +85,20 @@ lane :ui_tests do |options|
)
end
lane :accessibility_tests do |options|
reset_simulator = ENV.key?('CI')
run_tests(
scheme: "AccessibilityTests",
device: "iPhone 16 (18.5)",
ensure_devices_found: true,
prelaunch_simulator: false,
result_bundle: true,
number_of_retries: 0,
reset_simulator: reset_simulator
)
end
lane :integration_tests do
clear_derived_data()