* Initial plan
* Migrate 3 test files from XCTest to Swift Testing
- MediaUploadPreviewScreenViewModelTests: @MainActor @Suite struct with init(),
BundleFinder class for Bundle(for:), mutating test/setup functions,
[self] capture replacing [weak self] in closures
- NotificationManagerTests: @MainActor @Suite final class with init()/deinit,
expectation/fulfillment(of:) replaced with confirmation(...), test_ prefix stripped
- NotificationSettingsScreenViewModelTests: @MainActor @Suite struct with
init() throws, non-optional stored properties, test prefix stripped
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Migrate 3 XCTest files to Swift Testing
- NotificationSettingsEditScreenViewModelTests: @MainActor @Suite struct with init() throws, mutating test methods
- TimelineViewModelTests: @MainActor @Suite final class with init() async throws + deinit
- AttributedStringBuilderTests: @Suite struct with init() async throws
All XCT assertions replaced with #expect/#require/Issue.record
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Migrate 4 test files from XCTest to Swift Testing
- TimelineMediaPreviewViewModelTests: @Suite struct, mutating @Test funcs,
testLoadingItem renamed to loadingItem (called internally by other tests)
- ServerConfirmationScreenViewModelTests: @Suite final class with init()/deinit
- CompletionSuggestionServiceTests: @Suite struct with init()
- RoomFlowCoordinatorTests: @Suite final class with deinit
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Migrate 4 test files from XCTest to Swift Testing
- VoiceMessageRecorderTests: @Suite struct with init() async throws,
added BundleFinder class for Bundle lookup, migrated all assertions
- SpaceScreenViewModelTests: @Suite struct, private mutating setupViewModel,
all test funcs mutating, XCTestExpectation → confirmation
- RoomNotificationSettingsScreenViewModelTests: @Suite struct with
init() throws, cancellable tests marked mutating
- JoinRoomScreenViewModelTests: @Suite final class with init()/deinit,
XCTestExpectation → confirmation
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Migrate 6 test files from XCTestCase to Swift Testing
Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com>
* Fix trailing blank line in RoomPollsHistoryScreenViewModelTests
Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com>
* Migrate 3 test files from XCTest to Swift Testing
- MediaUploadingPreprocessorTests: @Suite final class with init()/deinit,
removed executionTimeAllowance, XCTAssertEqual(accuracy:) → abs(Double)
- SecurityAndPrivacyScreenViewModelTests: @MainActor @Suite final class,
5 expectation+fulfillment → await confirmation(...)
- CreateRoomViewModelTests: @MainActor @Suite final class,
4 expectation+fulfillment → await confirmation(...)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Migrate RoomScreenViewModelTests and RoomDetailsScreenViewModelTests to Swift Testing
- Replace XCTest with Testing framework
- RoomScreenViewModelTests: final class with init() async throws + deinit
- RoomDetailsScreenViewModelTests: struct with init() and mutating funcs
- Convert XCT assertions to #expect / Issue.record
- Convert XCTestExpectation patterns to confirmation { confirm in }
- Strip 'test' prefix from all test function names
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Migrate ComposerToolbarViewModelTests from XCTest to Swift Testing
- Replace import XCTest with import Testing
- Convert XCTestCase class to @MainActor @Suite final class
- Replace setUp()/tearDown() with init()/deinit
- Strip 'test' prefix from all 41 test method names and add @Test
- Replace XCTAssert* with #expect()/#require()
- Replace try XCTUnwrap() with try #require()
- Convert expectation+wait patterns to deferFulfillment with PassthroughSubject
- Convert isInverted expectation to boolean flag checked after await
- Use deferFulfillment on $viewState for state-transition tests
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
* Address comments with Copilot.
* Fix the failing tests.
* Fixed flaky tests (#5137)
resolved flaky tests
* Tweaks and fixes.
---------
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: pixlwave <6060466+pixlwave@users.noreply.github.com>
Co-authored-by: Doug <douglase@element.io>
Co-authored-by: Mauro <34335419+Velin92@users.noreply.github.com>
* improved defer fullfillment
* applied also for async streams
* fix xcodeproject
* better documentation
* restict deferFulfillment only for Publisher which can never fail
* Implement voice message variable playback speed
* Move playback speed string to Untranslated
https://github.com/element-hq/element-x-ios/pull/5121#discussion_r2822631371
* Address review feedback for voice message playback speed
- Persist voice message playback speed as an enum in AppSettings instead of storing an index.
- Update playback speed cycling to derive from enum allCases and safely fall back to `.default` if the stored value cannot be resolved.
- Apply runtime speed updates in AudioPlayer only when the player is in the `.playing` state.
- Keep MediaPlayerProviderTests formatting/indentation style intact while retaining mock playback speed setup.
- Regenerate preview snapshots for:
- PlaybackSpeedButton
- VoiceMessageRoomPlaybackView
- VoiceMessageRoomTimelineView
* Move VoiceMessagePlaybackSpeed outside AppSettings, remove speedRatio
* Stabilize PlaybackSpeedButton width
* Sync voice-message speed label
- Add voiceMessagePlaybackSpeed to TimelineViewState and bind it from appSettings.$voiceMessagePlaybackSpeed.
- Pass that timeline-level speed into VoiceMessageRoomPlaybackView and use it for PlaybackSpeedButton, so labels update consistently across items.
- Use @EnvironmentObject in VoiceMessageRoomTimelineContent so the view re-renders when timeline context state changes.
- In WaveformInteractionModifier, add .allowsHitTesting(showCursor) to the cursor interaction view so hidden pre-playback cursor hit area does not steal taps from the speed button.
* migrated a lot of unit tests to Swift Testing and added a new implementation for deferred fulfillment
more tests migration
Cleaned the code manually to establish some good patterns
more code improvements
some more code improvements
removed empty tests
update project
* more pr suggestions and cleanups
* removed the TestSetup pattern
* fixing claude not reusing tests
* pr suggestion + added indent rule to swiftformat so that we can prevent AIs to change that
* session verification now does not have a waiting screen, but the initial state instead presents a loading state. Everything is also handled with one single action
* use progress view in place of the spinner icon
* change progress view tint
* compound is now using 6.2 and main actor isolation + some tweaks to make it build tests and EX
* better handling of the nonisolated context for CompoundUIColors
* improving docs
* fix comment
* remove unused Sendable conformance
* replace NavigationStack with ElementNavigationStack to allow the content to be rendered without a NavigationStack in a11y tests
* fix a11y tests
* update xcodeproject
* swiftformat fix
* use iOS 26.1 for CI
* use a wrapper to solve the issue for a11y tests
* ElementNavigationStack only uses the trick in DEBUG mode, and added a swiftlint rule to prevent the usage of NavigationStack
* Use the old state machine configuration style.
* Test starting the space settings flow in UI tests.
* Test starting the create space room flow in UI tests.
* Lock the LinkNewDeviceScreen to portrait.
* Add cancel buttons to the QR Code errors and handle cancel/startOver correctly.
* Use the shared QRCodeErrorView in the LinkNewDeviceScreen.
* Clarify the different QR Error/ErrorStates a bit more.
* Update snapshots.
* Add an initial implementation of the receivedWhileOfflineNotification.
* Only deliver a single receivedWhileOffline notification per boot and clarify the API.
* Add a 15-minute threshold for the receiveWhileOfflineNotification.
* Stop using Rust's JoinRule.private in mocks.
It isn't used anywhere else (see MSC4413 for more context).
* Use our own JoinRule (and AllowRule) types.
* Update ElementX/Sources/Services/Room/JoinRule.swift
Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
---------
Co-authored-by: Stefan Ceriu <stefan.ceriu@gmail.com>
Bump the RustSDK to v26.02.03
Fix breaking changes and add support for the new background task error reporting delegate and the new room invite latest event.
* Debugging with Notifications.
* Don't run the NSE until the device is unlocked.
* Let the NSE run long enough to deliver the default notification content.
Turns out that exit(0) results in the notification be discarded when you have the notification filtering entitlement.
* Remove debugging notifications.
---------
Co-authored-by: Stefan Ceriu <stefanc@matrix.org>
* Rewrite the CallService's incoming push handling to async
* Revert "Rewrite the CallService's incoming push handling to async"
* Make sure to call the completion blocks on all branches after delivering incoming pushes
Fixes `Killing app because it never posted an incoming call to the system after receiving a PushKit VoIP push` crashes
Initially tried replacing the callback based API with the async one but notifications stopped coming in. See associated PR for commits and details.