From 96db3d7c2732b1f08aebc3c9df05807ea8cd3b2f Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Mon, 22 Dec 2025 15:38:31 +0100 Subject: [PATCH 01/12] test: Fix visionOS compilation of tests - Added visionOS 26 configuration to GitHub Actions workflow. - Modified various files to support visionOS, including conditional compilation for UIKit and related tests. - Updated runtime context for Mac Catalyst to reflect correct descriptions. - Enhanced test coverage for device context on visionOS. --- .github/workflows/test.yml | 8 +++++++ CHANGELOG.md | 1 + .../SentryTestUtils-ObjC-BridgingHeader.h | 6 ----- .../Sources/TestDisplayLinkWrapper.swift | 8 +++++-- Sources/Sentry/SentryBuildAppStartSpans.m | 2 +- Sources/Sentry/SentrySpan.m | 6 ++--- Sources/Sentry/SentryTracer.m | 20 ++++++++--------- Sources/Sentry/include/SentrySpan.h | 4 ++-- .../SentryCrash/SentryCrashWrapper.swift | 2 +- Tests/SentryTests/Helper/SentryDeviceTests.m | 18 +++++++++++++++ .../SentryANRTrackingIntegrationTests.swift | 2 +- .../SentryTimeToDisplayTrackerTest.swift | 3 +-- .../Session/SentrySessionTrackerTests.swift | 22 +++++++++---------- .../PrivateSentrySDKOnlyTests.swift | 12 +++++----- Tests/SentryTests/Protocol/TestData.swift | 6 ++--- Tests/SentryTests/SentryClientTests.swift | 2 +- .../SentryCrash/SentryCrashWrapperTests.swift | 3 ++- Tests/SentryTests/SentryHubTests.swift | 2 +- Tests/SentryTests/SentryOptionsTest.m | 7 +++--- Tests/SentryTests/SentrySDKTests.swift | 2 +- .../SentryTests/SentryTests-Bridging-Header.h | 6 +++-- .../SentryTests/TestSentryNSApplication.swift | 2 +- .../SentryBuildAppStartSpansTests.swift | 2 +- .../Transaction/SentryTracerTests.swift | 2 +- Tests/SentryTests/UIImageHelperTests.swift | 4 +++- 25 files changed, 92 insertions(+), 60 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 16d51b972d6..8971aa2082d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -370,6 +370,14 @@ jobs: device: "Apple TV" scheme: "Sentry" + # visionOS 26 + - name: visionOS 26 Sentry + runs-on: macos-26 + xcode: "26.1.1" + test-destination-os: "26.1" + platform: "visionOS" + scheme: "Sentry" + # This check validates that either all unit tests passed or were skipped, which allows us # to make unit tests a required check with only running the unit tests when required. # So, we don't have to run unit tests, for example, for Changelog or ReadMe changes. diff --git a/CHANGELOG.md b/CHANGELOG.md index 91539b2e739..a02ead23130 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Change default attributes of Logs to only include user attributes when `options.sendDefaultPii = true` (#7055) - Rename log attribute `sentry.trace.parent_span_id` to `span_id` (#7055) - Fixes stacktraces for MetricKit events (#6908) +- Fix compilation for visionOS (#7081) ## 9.1.0 diff --git a/SentryTestUtils/Headers/SentryTestUtils-ObjC-BridgingHeader.h b/SentryTestUtils/Headers/SentryTestUtils-ObjC-BridgingHeader.h index 8b541de2194..8e155820bb2 100644 --- a/SentryTestUtils/Headers/SentryTestUtils-ObjC-BridgingHeader.h +++ b/SentryTestUtils/Headers/SentryTestUtils-ObjC-BridgingHeader.h @@ -1,11 +1,5 @@ #import "SentryDefines.h" -#if TARGET_OS_IOS || TARGET_OS_TV -# define SENTRY_UIKIT_AVAILABLE 1 -#else -# define SENTRY_UIKIT_AVAILABLE 0 -#endif - #if SENTRY_HAS_UIKIT # import "SentryAppStartTracker.h" # import "SentryDefaultUIViewControllerPerformanceTracker.h" diff --git a/SentryTestUtils/Sources/TestDisplayLinkWrapper.swift b/SentryTestUtils/Sources/TestDisplayLinkWrapper.swift index 54f207e54e4..81f75a33f90 100644 --- a/SentryTestUtils/Sources/TestDisplayLinkWrapper.swift +++ b/SentryTestUtils/Sources/TestDisplayLinkWrapper.swift @@ -1,7 +1,7 @@ import Foundation @_spi(Private) @testable import Sentry -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) public enum GPUFrame { case normal @@ -18,7 +18,7 @@ public enum FrameRate: UInt64 { } } -@_spi(Private) public class TestDisplayLinkWrapper: SentryDisplayLinkWrapper, SentryReplayDisplayLinkWrapper { +@_spi(Private) public class TestDisplayLinkWrapper: SentryDisplayLinkWrapper { public var target: AnyObject! public var selector: Selector! public var currentFrameRate: FrameRate = .low @@ -146,3 +146,7 @@ public enum FrameRate: UInt64 { } #endif + +#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +extension TestDisplayLinkWrapper: SentryReplayDisplayLinkWrapper {} +#endif diff --git a/Sources/Sentry/SentryBuildAppStartSpans.m b/Sources/Sentry/SentryBuildAppStartSpans.m index e3e0b5e60f8..38b6fb649de 100644 --- a/Sources/Sentry/SentryBuildAppStartSpans.m +++ b/Sources/Sentry/SentryBuildAppStartSpans.m @@ -7,7 +7,7 @@ #import "SentryTracer.h" #import -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION SentrySpan * sentryBuildAppStartSpan( diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index 1e5e782a8ca..55cc1e468b7 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -46,7 +46,7 @@ @implementation SentrySpan { } - (instancetype)initWithContext:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:(nullable SentryFramesTracker *)framesTracker; #endif // SENTRY_HAS_UIKIT { @@ -65,7 +65,7 @@ - (instancetype)initWithContext:(SentrySpanContext *)context getThreadName:currentThread]; } -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION _framesTracker = framesTracker; if (_framesTracker.isRunning) { SentryScreenFrames *currentFrames = _framesTracker.currentFrames; @@ -137,7 +137,7 @@ - (void)stopObservingContinuousProfiling - (instancetype)initWithTracer:(SentryTracer *)tracer context:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:(nullable SentryFramesTracker *)framesTracker { if (self = [self initWithContext:context framesTracker:framesTracker]) { diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 5f41a8b5d4c..39e027c80ec 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -30,7 +30,7 @@ # import "SentryProfiledTracerConcurrency.h" #endif // SENTRY_TARGET_PROFILING_SUPPORTED -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION # import "SentryAppStartMeasurement.h" # import "SentryBuildAppStartSpans.h" #endif // SENTRY_HAS_UIKIT @@ -39,7 +39,7 @@ static const void *spanTimestampObserver = &spanTimestampObserver; -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION /** * The maximum amount of seconds the app start measurement end time and the start time of the * transaction are allowed to be apart. @@ -114,7 +114,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti configuration:(SentryTracerConfiguration *)configuration; { if (!(self = [super initWithContext:transactionContext -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:SentryDependencyContainer.sharedInstance.framesTracker #endif // SENTRY_HAS_UIKIT ])) { @@ -390,7 +390,7 @@ - (BOOL)isAutoGeneratedTransaction SentrySpan *child = [[SentrySpan alloc] initWithTracer:self context:context -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:SentryDependencyContainer.sharedInstance.framesTracker #endif // SENTRY_HAS_UIKIT ]; @@ -615,13 +615,13 @@ - (BOOL)finishTracer:(SentrySpanStatus)unfinishedSpansFinishStatus shouldCleanUp } [super finishWithStatus:_finishStatus]; } -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION appStartMeasurement = [self getAppStartMeasurement]; if (appStartMeasurement != nil) { [self updateStartTime:appStartMeasurement.appStartTimestamp]; } -#endif // SENTRY_HAS_UIKIT +#endif // SENTRY_HAS_UIKIT && !TARGET_OS_VISION if (shouldCleanUp) { [self.delegate tracerDidFinish:self]; @@ -721,7 +721,7 @@ - (SentryTransaction *)toTransaction { NSUInteger capacity; -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION [self addFrameStatistics]; NSArray> *appStartSpans = sentryBuildAppStartSpans(self, appStartMeasurement); @@ -736,7 +736,7 @@ - (SentryTransaction *)toTransaction [spans addObjectsFromArray:_children]; } -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION [spans addObjectsFromArray:appStartSpans]; #endif // SENTRY_HAS_UIKIT @@ -763,7 +763,7 @@ - (SentryTransaction *)toTransaction [debugImageProvider getDebugImagesFromCacheForFrames:framesOfAllSpans]; } -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION [self addAppStartMeasurements:transaction]; if ([viewNames count] > 0) { @@ -774,7 +774,7 @@ - (SentryTransaction *)toTransaction return transaction; } -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION - (nullable SentryAppStartMeasurement *)getAppStartMeasurement SENTRY_DISABLE_THREAD_SANITIZER( "double-checked lock produce false alarms") diff --git a/Sources/Sentry/include/SentrySpan.h b/Sources/Sentry/include/SentrySpan.h index b15dbe69428..bcc9fba7459 100644 --- a/Sources/Sentry/include/SentrySpan.h +++ b/Sources/Sentry/include/SentrySpan.h @@ -96,7 +96,7 @@ SENTRY_NO_INIT */ - (instancetype)initWithTracer:(SentryTracer *)transaction context:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:(nullable SentryFramesTracker *)framesTracker; #endif // SENTRY_HAS_UIKIT ; @@ -106,7 +106,7 @@ SENTRY_NO_INIT * @param context This span context information. */ - (instancetype)initWithContext:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:(nullable SentryFramesTracker *)framesTracker; #endif // SENTRY_HAS_UIKIT ; diff --git a/Sources/Swift/SentryCrash/SentryCrashWrapper.swift b/Sources/Swift/SentryCrash/SentryCrashWrapper.swift index 3f02c126d67..8c07195307a 100644 --- a/Sources/Swift/SentryCrash/SentryCrashWrapper.swift +++ b/Sources/Swift/SentryCrash/SentryCrashWrapper.swift @@ -210,7 +210,7 @@ public final class SentryCrashWrapper: NSObject { if self.processInfoWrapper.isMacCatalystApp { runtimeContext["name"] = "Mac Catalyst App" - runtimeContext["raw_description"] = "raw_description" + runtimeContext["raw_description"] = "mac-catalyst-app" } } diff --git a/Tests/SentryTests/Helper/SentryDeviceTests.m b/Tests/SentryTests/Helper/SentryDeviceTests.m index e71c1528f29..cd69d2ad2f7 100644 --- a/Tests/SentryTests/Helper/SentryDeviceTests.m +++ b/Tests/SentryTests/Helper/SentryDeviceTests.m @@ -79,6 +79,18 @@ - (void)testCPUArchitecture // TODO: create a watch UI test target to test this branch as it cannot run on the watch // simulator SENTRY_ASSERT_CONTAINS(arch, @"arm"); // Real Watches +#elif TARGET_OS_VISION +# if TARGET_OS_SIMULATOR +# if TARGET_CPU_ARM64 + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // Vision Pro simulator on M1 macs +# elif TARGET_CPU_X86_64 + SENTRY_ASSERT_CONTAINS(arch, @"x86"); // Vision Pro simulator on Intel macs +# else + XCTFail(@"Unexpected CPU type on test host."); +# endif // TARGET_CPU_ARM64 +# else + SENTRY_ASSERT_CONTAINS(arch, @"arm"); // Real Vision Pro devices +# endif #else XCTFail(@"Unexpected device OS"); #endif @@ -127,6 +139,8 @@ - (void)testOSName #elif TARGET_OS_WATCH // TODO: create a watch UI test target to test this branch SENTRY_ASSERT_EQUAL(osName, @"watchOS"); +#elif TARGET_OS_VISION + SENTRY_ASSERT_EQUAL(osName, @"visionOS"); #else XCTFail(@"Unexpected device OS"); #endif @@ -161,6 +175,8 @@ - (void)testDeviceModel // TODO: create a watch UI test target to test this branch as it cannot run on the watch // simulator SENTRY_ASSERT_CONTAINS(modelName, @"Watch"); +#elif TARGET_OS_VISION + SENTRY_ASSERT_CONTAINS(modelName, @"RealityDevice"); #else XCTFail(@"Unexpected target OS"); #endif @@ -205,6 +221,8 @@ - (void)testSimulatedDeviceModel // TODO: create a watch UI test target to test this branch as it cannot run on the watch // simulator SENTRY_ASSERT_CONTAINS(modelName, @"Watch"); +# elif TARGET_OS_VISION + SENTRY_ASSERT_CONTAINS(modelName, @"RealityDevice"); # else XCTFail(@"Unexpected device OS"); # endif diff --git a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift index b4250affb77..32940e92e37 100644 --- a/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift +++ b/Tests/SentryTests/Integrations/ANR/SentryANRTrackingIntegrationTests.swift @@ -79,7 +79,7 @@ class SentryANRTrackingIntegrationTests: SentrySDKIntegrationTestsBase { let tracker = try XCTUnwrap(Dynamic(sut).tracker.asAnyObject as? SentryANRTracker) -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) XCTAssertTrue(tracker.helper is SentryANRTrackerV2, "Expected SentryANRTrackerV2, but got \(type(of: tracker))") #else XCTAssertTrue(tracker.helper is SentryANRTrackerV1, "Expected SentryANRTrackerV1 on macOS, but got \(type(of: tracker))") diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift index 81a9cc49ee8..50a5fe2c78a 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift @@ -3,10 +3,9 @@ import Foundation @_spi(Private) import SentryTestUtils import XCTest -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) - class TestDelayedWrapper: SentryDelayedFramesTracker {} +#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) class SentryTimeToDisplayTrackerTest: XCTestCase { private class Fixture { diff --git a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift index c0078e64d21..0b64d5c8ee8 100644 --- a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift @@ -13,7 +13,7 @@ class SentrySessionTrackerTests: XCTestCase { let client: TestClient! let sentryCrash: TestSentryCrashWrapper - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT let _application: TestSentryUIApplication #else let _application: TestSentryNSApplication @@ -38,7 +38,7 @@ class SentrySessionTrackerTests: XCTestCase { sentryCrash = TestSentryCrashWrapper(processInfoWrapper: ProcessInfo.processInfo) - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT _application = TestSentryUIApplication() _application.unsafeApplicationState = .inactive #else @@ -537,7 +537,7 @@ class SentrySessionTrackerTests: XCTestCase { // MARK: - Helpers private func startSutInAppDelegate() { - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // The Sentry SDK should be initialized in the `UIAppDelegate.didFinishLaunchingWithOptions` // At this point the application state is `inactive`, because the app just launched but did not // become the active app yet. @@ -565,7 +565,7 @@ class SentrySessionTrackerTests: XCTestCase { // We remove the observers, to ensure future notifications are not handled. sut.removeObservers() - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // When the app stops, the app state is `inactive`. // This can be observed by viewing the application state in `UIAppDelegate.applicationDidEnterBackground`. fixture._application.unsafeApplicationState = .inactive @@ -580,7 +580,7 @@ class SentrySessionTrackerTests: XCTestCase { private func crashSut() { sut.removeObservers() - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // When the app stops, the app state is `inactive`. // // This can be observed by viewing the application state in `UIAppDelegate.applicationDidEnterBackground`. @@ -600,7 +600,7 @@ class SentrySessionTrackerTests: XCTestCase { } private func goToForeground() { - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // When the app becomes active, the app state is `active`. // This can be observed by viewing the application state in `UIAppDelegate.applicationDidBecomeActive`. fixture._application.unsafeApplicationState = .active @@ -622,7 +622,7 @@ class SentrySessionTrackerTests: XCTestCase { private func goToBackground() { // Before an app goes to background, it is still active and will resign from being active. willResignActive() - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // It is expected that the app state is background when the didEnterBackground is called fixture._application.unsafeApplicationState = .background fixture.notificationCenter @@ -642,7 +642,7 @@ class SentrySessionTrackerTests: XCTestCase { } private func willResignActive() { - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // When the app is about to resign being active, it is still active. // // This can be observed by viewing the application state in `UIAppDelegate.applicationWillResignActive`. @@ -665,7 +665,7 @@ class SentrySessionTrackerTests: XCTestCase { private func hybridSdkDidBecomeActive() { // When an app did become active, it is in the active state. - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT fixture._application.unsafeApplicationState = .active #else fixture._application.setIsActive(true) @@ -687,7 +687,7 @@ class SentrySessionTrackerTests: XCTestCase { } private func willTerminate() { - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT // When terminating an app, it will first move to the background and then terminate. // // This can be observed by viewing the application state in `UIAppDelegate.applicationWillTerminate`. @@ -876,7 +876,7 @@ class SentrySessionTrackerTests: XCTestCase { private func postHybridSdkDidBecomeActiveNotification() { // When the hybrid SDK posts this notification, the app should be in active state - #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) + #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT fixture._application.unsafeApplicationState = .active #else fixture._application.setIsActive(true) diff --git a/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift b/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift index 3ea98fa28eb..208583dbaa5 100644 --- a/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift +++ b/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift @@ -240,7 +240,7 @@ class PrivateSentrySDKOnlyTests: XCTestCase { XCTAssertEqual(PrivateSentrySDKOnly.options.enabled, true) } - #if !os(tvOS) && !os(watchOS) + #if !os(tvOS) && !os(watchOS) && !os(visionOS) /** * Smoke Tests profiling via PrivateSentrySDKOnly. Actual profiling unit tests are done elsewhere. */ @@ -349,6 +349,7 @@ class PrivateSentrySDKOnlyTests: XCTestCase { #endif #if canImport(UIKit) + #if SENTRY_TARGET_REPLAY_SUPPORTED func testCaptureReplayShouldCallReplayIntegration() throws { guard #available(iOS 16.0, tvOS 16.0, *) else { return } @@ -443,6 +444,11 @@ class PrivateSentrySDKOnlyTests: XCTestCase { XCTAssertTrue(redactBuilder.isRedactContainerClassTestOnly(RedactContainer.self)) } + private func getFirstIntegrationAsReplay() throws -> SentrySessionReplayIntegration { + return try XCTUnwrap(SentrySDKInternal.currentHub().installedIntegrations().first as? SentrySessionReplayIntegration) + } + #endif // SENTRY_TARGET_REPLAY_SUPPORTED + func testAddExtraSdkPackages() throws { PrivateSentrySDKOnly.addSdkPackage("package1", version: "version1") PrivateSentrySDKOnly.addSdkPackage("package2", version: "version2") @@ -462,10 +468,6 @@ class PrivateSentrySDKOnlyTests: XCTestCase { } } - private func getFirstIntegrationAsReplay() throws -> SentrySessionReplayIntegration { - return try XCTUnwrap(SentrySDKInternal.currentHub().installedIntegrations().first as? SentrySessionReplayIntegration) - } - private let VALID_REPLAY_ID = "0eac7ab503354dd5819b03e263627a29" #endif diff --git a/Tests/SentryTests/Protocol/TestData.swift b/Tests/SentryTests/Protocol/TestData.swift index e9aff3b8815..2da2e043ab9 100644 --- a/Tests/SentryTests/Protocol/TestData.swift +++ b/Tests/SentryTests/Protocol/TestData.swift @@ -2,7 +2,7 @@ import Sentry @_spi(Private) import Sentry @_spi(Private) import SentryTestUtils -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) import UIKit #endif @@ -340,8 +340,8 @@ class TestData { return request } - #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) - + #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) || os(visionOS) + static func getAppStartMeasurement( type: SentryAppStartType, appStartTimestamp: Date = TestData.timestamp, diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index 06876f56267..0559e9af90f 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -1953,7 +1953,7 @@ class SentryClientTests: XCTestCase { if !SentryDependencyContainer.sharedInstance().crashWrapper.isBeingTraced { expectedIntegrations = ["ANRTracking"] + expectedIntegrations } -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) expectedIntegrations.append("FramesTracking") #endif // os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) diff --git a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift index a272e046918..378e8d12363 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift @@ -1,4 +1,5 @@ @_spi(Private) @testable import Sentry +@_spi(Private) import SentryTestUtils import XCTest final class SentryCrashWrapperTests: XCTestCase { @@ -129,7 +130,7 @@ final class SentryCrashWrapperTests: XCTestCase { let runtimeContext = try XCTUnwrap(scope.contextDictionary["runtime"] as? [String: Any]) XCTAssertEqual(runtimeContext["name"] as? String, "Mac Catalyst App") - XCTAssertEqual(runtimeContext["raw_description"] as? String, "raw_description") + XCTAssertEqual(runtimeContext["raw_description"] as? String, "mac-catalyst-app") #endif } } diff --git a/Tests/SentryTests/SentryHubTests.swift b/Tests/SentryTests/SentryHubTests.swift index 235c3e294f4..d9c3f8c8c83 100644 --- a/Tests/SentryTests/SentryHubTests.swift +++ b/Tests/SentryTests/SentryHubTests.swift @@ -238,7 +238,7 @@ class SentryHubTests: XCTestCase { // Assert let runtimeContext = try XCTUnwrap (hub.scope.contextDictionary["runtime"] as? [String: String]) XCTAssertEqual(runtimeContext["name"], "Mac Catalyst App") - XCTAssertEqual(runtimeContext["raw_description"], "raw_description") + XCTAssertEqual(runtimeContext["raw_description"], "mac-catalyst-app") } func testScopeNotEnriched_WhenScopeIsNil() { diff --git a/Tests/SentryTests/SentryOptionsTest.m b/Tests/SentryTests/SentryOptionsTest.m index 9ca5afb041e..bb837bc1f98 100644 --- a/Tests/SentryTests/SentryOptionsTest.m +++ b/Tests/SentryTests/SentryOptionsTest.m @@ -359,7 +359,7 @@ - (void)testBeforeSendSpan SentryOptions *options = [self getValidOptions:@{ @"beforeSendSpan" : callback }]; options.beforeSendSpan( [[SentrySpan alloc] initWithContext:[[SentrySpanContext alloc] initWithOperation:@""] -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION framesTracker:NULL #endif ]); @@ -713,7 +713,7 @@ - (void)assertDefaultValues:(SentryOptions *)options XCTAssertEqual(200 * 1024 * 1024, options.maxAttachmentSize); XCTAssertEqual(NO, options.sendDefaultPii); XCTAssertTrue(options.enableAutoPerformanceTracing); -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && SENTRY_TARGET_REPLAY_SUPPORTED XCTAssertTrue(options.enableUIViewControllerTracing); XCTAssertFalse(options.attachScreenshot); XCTAssertEqual(3.0, options.idleTimeout); @@ -893,6 +893,7 @@ - (void)testEnablePreWarmedAppStartTracking [self testBooleanField:@"enablePreWarmedAppStartTracing" defaultValue:YES]; } +# if SENTRY_TARGET_REPLAY_SUPPORTED - (void)testSessionReplaySettingsInit { if (@available(iOS 16.0, tvOS 16.0, *)) { @@ -912,7 +913,7 @@ - (void)testSessionReplaySettingsDefaults XCTAssertEqual(options.sessionReplay.onErrorSampleRate, 0); } } - +# endif // SENTRY_TARGET_REPLAY_SUPPORTED #endif // SENTRY_HAS_UIKIT #if SENTRY_HAS_METRIC_KIT diff --git a/Tests/SentryTests/SentrySDKTests.swift b/Tests/SentryTests/SentrySDKTests.swift index ec65dd6fa74..ef124c49ca3 100644 --- a/Tests/SentryTests/SentrySDKTests.swift +++ b/Tests/SentryTests/SentrySDKTests.swift @@ -136,7 +136,7 @@ class SentrySDKTests: XCTestCase { if !SentryDependencyContainer.sharedInstance().crashWrapper.isBeingTraced { expectedIntegrations.append("SentryANRTrackingIntegration") } -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) expectedIntegrations.append("SentryFramesTrackingIntegration") #endif // os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) diff --git a/Tests/SentryTests/SentryTests-Bridging-Header.h b/Tests/SentryTests/SentryTests-Bridging-Header.h index b5ebf4c6a64..0f2dfb558f0 100644 --- a/Tests/SentryTests/SentryTests-Bridging-Header.h +++ b/Tests/SentryTests/SentryTests-Bridging-Header.h @@ -5,8 +5,10 @@ #if SENTRY_HAS_UIKIT # import "MockUIScene.h" # import "SentryDefaultUIViewControllerPerformanceTracker.h" -# import "SentrySessionReplayIntegration+Private.h" -# import "SentrySessionReplayIntegration+Test.h" +# if SENTRY_TARGET_REPLAY_SUPPORTED +# import "SentrySessionReplayIntegration+Private.h" +# import "SentrySessionReplayIntegration+Test.h" +# endif // SENTRY_TARGET_REPLAY_SUPPORTED # import "SentryUIEventTracker.h" # import "SentryUIEventTrackerTransactionMode.h" # import "SentryUIEventTrackingIntegration.h" diff --git a/Tests/SentryTests/TestSentryNSApplication.swift b/Tests/SentryTests/TestSentryNSApplication.swift index acf4e0ba5cf..888bb80f5d4 100644 --- a/Tests/SentryTests/TestSentryNSApplication.swift +++ b/Tests/SentryTests/TestSentryNSApplication.swift @@ -1,6 +1,6 @@ @_spi(Private) @testable import Sentry -#if !(os(iOS) || targetEnvironment(macCatalyst) || os(tvOS)) +#if !(os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS)) class TestSentryNSApplication: SentryApplication { private var _underlyingIsActive = true func setIsActive(_ isActive: Bool) { diff --git a/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift b/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift index b78bd129b3f..31bd88407c3 100644 --- a/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift +++ b/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift @@ -1,7 +1,7 @@ @testable import Sentry import XCTest -#if canImport(UIKit) +#if canImport(UIKit) && !os(visionOS) class SentryBuildAppStartSpansTests: XCTestCase { func testSentryBuildAppStartSpans_appStartMeasurementIsNil_shouldNotReturnAnySpans() { diff --git a/Tests/SentryTests/Transaction/SentryTracerTests.swift b/Tests/SentryTests/Transaction/SentryTracerTests.swift index bc001e564e8..2c06ea4a7d3 100644 --- a/Tests/SentryTests/Transaction/SentryTracerTests.swift +++ b/Tests/SentryTests/Transaction/SentryTracerTests.swift @@ -615,7 +615,7 @@ class SentryTracerTests: XCTestCase { } func testIdleTimeout_TracerDeallocated() throws { -#if !os(tvOS) && !os(watchOS) +#if !os(tvOS) && !os(watchOS) && !os(visionOS) if sentry_threadSanitizerIsPresent() { throw XCTSkip("doesn't currently work with TSAN enabled. the tracer instance remains retained by something in the TSAN dylib, and we cannot debug the memory graph with TSAN attached to see what is retaining it. it's likely out of our control.") } diff --git a/Tests/SentryTests/UIImageHelperTests.swift b/Tests/SentryTests/UIImageHelperTests.swift index 1b92c573f3d..f8292ac7ac3 100644 --- a/Tests/SentryTests/UIImageHelperTests.swift +++ b/Tests/SentryTests/UIImageHelperTests.swift @@ -1,4 +1,5 @@ #if canImport(UIKit) +#if os(iOS) || os(tvOS) import Foundation @testable import Sentry import XCTest @@ -61,4 +62,5 @@ class UIImageHelperTests: XCTestCase { } } -#endif +#endif // os(iOS) || os(tvOS) +#endif // canImport(UIKit) From 4061b1b7ee6ea7cc90d34f27262f6cf2bd92d383 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Mon, 22 Dec 2025 15:43:48 +0100 Subject: [PATCH 02/12] Apply suggestions from code review --- Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift | 2 +- Tests/SentryTests/SentryHubTests.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift index 378e8d12363..6226b11a73a 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift @@ -130,7 +130,7 @@ final class SentryCrashWrapperTests: XCTestCase { let runtimeContext = try XCTUnwrap(scope.contextDictionary["runtime"] as? [String: Any]) XCTAssertEqual(runtimeContext["name"] as? String, "Mac Catalyst App") - XCTAssertEqual(runtimeContext["raw_description"] as? String, "mac-catalyst-app") + XCTAssertEqual(runtimeContext["raw_description"] as? String, "raw_description") #endif } } diff --git a/Tests/SentryTests/SentryHubTests.swift b/Tests/SentryTests/SentryHubTests.swift index d9c3f8c8c83..235c3e294f4 100644 --- a/Tests/SentryTests/SentryHubTests.swift +++ b/Tests/SentryTests/SentryHubTests.swift @@ -238,7 +238,7 @@ class SentryHubTests: XCTestCase { // Assert let runtimeContext = try XCTUnwrap (hub.scope.contextDictionary["runtime"] as? [String: String]) XCTAssertEqual(runtimeContext["name"], "Mac Catalyst App") - XCTAssertEqual(runtimeContext["raw_description"], "mac-catalyst-app") + XCTAssertEqual(runtimeContext["raw_description"], "raw_description") } func testScopeNotEnriched_WhenScopeIsNil() { From d5c4d5d8263998bffe8cdf546a70a3e35cf9f3e3 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Mon, 22 Dec 2025 15:53:30 +0100 Subject: [PATCH 03/12] feat: Add support for visionOS in Xcode build script - Introduced a new destination configuration for visionOS Simulator in the sentry-xcodebuild.sh script. --- scripts/sentry-xcodebuild.sh | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/scripts/sentry-xcodebuild.sh b/scripts/sentry-xcodebuild.sh index 2707fd77120..ac14603f5a6 100755 --- a/scripts/sentry-xcodebuild.sh +++ b/scripts/sentry-xcodebuild.sh @@ -107,6 +107,10 @@ case $PLATFORM in DESTINATION="platform=tvOS Simulator,OS=$OS,name=Apple TV" ;; +"visionOS") + DESTINATION="platform=visionOS Simulator,OS=$OS,name=Apple Vision Pro" + ;; + *) echo "Xcode Test: Can't find destination for platform '$PLATFORM'" exit 1 From 6171f5f88f093bac0a191039d6a84fd2520c0bd9 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 09:06:40 +0100 Subject: [PATCH 04/12] fix: Update runtime context description for Mac Catalyst - Adjusted the runtime context's raw description for Mac Catalyst from "raw_description" to "mac-catalyst-app" in SentryHubTests and SentryCrashWrapperTests. - Modified conditional compilation in SentrySpan.m to exclude visionOS from UIKit checks. --- Sources/Sentry/SentrySpan.m | 4 ++-- Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift | 2 +- Tests/SentryTests/SentryHubTests.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index 55cc1e468b7..f40abcdd96e 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -258,7 +258,7 @@ - (void)finishWithStatus:(SentrySpanStatus)status (unsigned long long)SentryDependencyContainer.sharedInstance.dateProvider.systemTime); } -#if SENTRY_HAS_UIKIT +#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION if (_framesTracker.isRunning) { CFTimeInterval framesDelay = [_framesTracker getFramesDelaySPI:_startSystemTime @@ -286,7 +286,7 @@ - (void)finishWithStatus:(SentrySpanStatus)status } } -#endif // SENTRY_HAS_UIKIT +#endif // SENTRY_HAS_UIKIT && !TARGET_OS_VISION if (self.tracer == nil) { SENTRY_LOG_DEBUG( diff --git a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift index 6226b11a73a..378e8d12363 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift @@ -130,7 +130,7 @@ final class SentryCrashWrapperTests: XCTestCase { let runtimeContext = try XCTUnwrap(scope.contextDictionary["runtime"] as? [String: Any]) XCTAssertEqual(runtimeContext["name"] as? String, "Mac Catalyst App") - XCTAssertEqual(runtimeContext["raw_description"] as? String, "raw_description") + XCTAssertEqual(runtimeContext["raw_description"] as? String, "mac-catalyst-app") #endif } } diff --git a/Tests/SentryTests/SentryHubTests.swift b/Tests/SentryTests/SentryHubTests.swift index 235c3e294f4..d9c3f8c8c83 100644 --- a/Tests/SentryTests/SentryHubTests.swift +++ b/Tests/SentryTests/SentryHubTests.swift @@ -238,7 +238,7 @@ class SentryHubTests: XCTestCase { // Assert let runtimeContext = try XCTUnwrap (hub.scope.contextDictionary["runtime"] as? [String: String]) XCTAssertEqual(runtimeContext["name"], "Mac Catalyst App") - XCTAssertEqual(runtimeContext["raw_description"], "raw_description") + XCTAssertEqual(runtimeContext["raw_description"], "mac-catalyst-app") } func testScopeNotEnriched_WhenScopeIsNil() { From bf904a1d373a6b8d8f63a14ef01df6c4793e3a9b Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 09:09:01 +0100 Subject: [PATCH 05/12] update changelog --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a02ead23130..ce5af7fda0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,7 @@ - Change default attributes of Logs to only include user attributes when `options.sendDefaultPii = true` (#7055) - Rename log attribute `sentry.trace.parent_span_id` to `span_id` (#7055) - Fixes stacktraces for MetricKit events (#6908) -- Fix compilation for visionOS (#7081) +- Fix Mac Catalyst runtime context tests to expect correct `"mac-catalyst-app"` value instead of `"raw_description"` (#7081) ## 9.1.0 From 3943388b40817e50c39080faea059cbc71d15f72 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 09:09:20 +0100 Subject: [PATCH 06/12] update changelog --- CHANGELOG.md | 1 - 1 file changed, 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b5e302ecc25..ce5af7fda0a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,7 +9,6 @@ - Rename log attribute `sentry.trace.parent_span_id` to `span_id` (#7055) - Fixes stacktraces for MetricKit events (#6908) - Fix Mac Catalyst runtime context tests to expect correct `"mac-catalyst-app"` value instead of `"raw_description"` (#7081) -- Fix `raw_description` in `runtime` context on Mac Catalyst (#7082) ## 9.1.0 From 51f16603503b9ad2886c8baaa27010f178d832b1 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 09:36:30 +0100 Subject: [PATCH 07/12] fix compilation of macOS tests --- .../UIViewController/SentryTimeToDisplayTrackerTest.swift | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift index 50a5fe2c78a..1de740e14cd 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift @@ -3,7 +3,9 @@ import Foundation @_spi(Private) import SentryTestUtils import XCTest +#if !os(macOS) class TestDelayedWrapper: SentryDelayedFramesTracker {} +#endif // !os(macOS) #if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) class SentryTimeToDisplayTrackerTest: XCTestCase { From ca0bf6d29fa241c2e3bec8f5b3e3830fe3b199ad Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 10:10:56 +0100 Subject: [PATCH 08/12] revert changes --- CHANGELOG.md | 1 - Sources/Sentry/SentryBuildAppStartSpans.m | 2 +- Sources/Sentry/SentrySpan.m | 10 +++++----- Sources/Sentry/SentryTracer.m | 20 +++++++++---------- Sources/Sentry/include/SentrySpan.h | 4 ++-- Tests/SentryTests/SentryClientTests.swift | 2 +- Tests/SentryTests/SentryOptionsTest.m | 2 +- .../Transaction/SentrySpanTests.swift | 6 +++--- 8 files changed, 23 insertions(+), 24 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ce5af7fda0a..91539b2e739 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,7 +8,6 @@ - Change default attributes of Logs to only include user attributes when `options.sendDefaultPii = true` (#7055) - Rename log attribute `sentry.trace.parent_span_id` to `span_id` (#7055) - Fixes stacktraces for MetricKit events (#6908) -- Fix Mac Catalyst runtime context tests to expect correct `"mac-catalyst-app"` value instead of `"raw_description"` (#7081) ## 9.1.0 diff --git a/Sources/Sentry/SentryBuildAppStartSpans.m b/Sources/Sentry/SentryBuildAppStartSpans.m index 38b6fb649de..e3e0b5e60f8 100644 --- a/Sources/Sentry/SentryBuildAppStartSpans.m +++ b/Sources/Sentry/SentryBuildAppStartSpans.m @@ -7,7 +7,7 @@ #import "SentryTracer.h" #import -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT SentrySpan * sentryBuildAppStartSpan( diff --git a/Sources/Sentry/SentrySpan.m b/Sources/Sentry/SentrySpan.m index f40abcdd96e..1e5e782a8ca 100644 --- a/Sources/Sentry/SentrySpan.m +++ b/Sources/Sentry/SentrySpan.m @@ -46,7 +46,7 @@ @implementation SentrySpan { } - (instancetype)initWithContext:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:(nullable SentryFramesTracker *)framesTracker; #endif // SENTRY_HAS_UIKIT { @@ -65,7 +65,7 @@ - (instancetype)initWithContext:(SentrySpanContext *)context getThreadName:currentThread]; } -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT _framesTracker = framesTracker; if (_framesTracker.isRunning) { SentryScreenFrames *currentFrames = _framesTracker.currentFrames; @@ -137,7 +137,7 @@ - (void)stopObservingContinuousProfiling - (instancetype)initWithTracer:(SentryTracer *)tracer context:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:(nullable SentryFramesTracker *)framesTracker { if (self = [self initWithContext:context framesTracker:framesTracker]) { @@ -258,7 +258,7 @@ - (void)finishWithStatus:(SentrySpanStatus)status (unsigned long long)SentryDependencyContainer.sharedInstance.dateProvider.systemTime); } -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT if (_framesTracker.isRunning) { CFTimeInterval framesDelay = [_framesTracker getFramesDelaySPI:_startSystemTime @@ -286,7 +286,7 @@ - (void)finishWithStatus:(SentrySpanStatus)status } } -#endif // SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#endif // SENTRY_HAS_UIKIT if (self.tracer == nil) { SENTRY_LOG_DEBUG( diff --git a/Sources/Sentry/SentryTracer.m b/Sources/Sentry/SentryTracer.m index 39e027c80ec..5f41a8b5d4c 100644 --- a/Sources/Sentry/SentryTracer.m +++ b/Sources/Sentry/SentryTracer.m @@ -30,7 +30,7 @@ # import "SentryProfiledTracerConcurrency.h" #endif // SENTRY_TARGET_PROFILING_SUPPORTED -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT # import "SentryAppStartMeasurement.h" # import "SentryBuildAppStartSpans.h" #endif // SENTRY_HAS_UIKIT @@ -39,7 +39,7 @@ static const void *spanTimestampObserver = &spanTimestampObserver; -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT /** * The maximum amount of seconds the app start measurement end time and the start time of the * transaction are allowed to be apart. @@ -114,7 +114,7 @@ - (instancetype)initWithTransactionContext:(SentryTransactionContext *)transacti configuration:(SentryTracerConfiguration *)configuration; { if (!(self = [super initWithContext:transactionContext -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:SentryDependencyContainer.sharedInstance.framesTracker #endif // SENTRY_HAS_UIKIT ])) { @@ -390,7 +390,7 @@ - (BOOL)isAutoGeneratedTransaction SentrySpan *child = [[SentrySpan alloc] initWithTracer:self context:context -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:SentryDependencyContainer.sharedInstance.framesTracker #endif // SENTRY_HAS_UIKIT ]; @@ -615,13 +615,13 @@ - (BOOL)finishTracer:(SentrySpanStatus)unfinishedSpansFinishStatus shouldCleanUp } [super finishWithStatus:_finishStatus]; } -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT appStartMeasurement = [self getAppStartMeasurement]; if (appStartMeasurement != nil) { [self updateStartTime:appStartMeasurement.appStartTimestamp]; } -#endif // SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#endif // SENTRY_HAS_UIKIT if (shouldCleanUp) { [self.delegate tracerDidFinish:self]; @@ -721,7 +721,7 @@ - (SentryTransaction *)toTransaction { NSUInteger capacity; -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT [self addFrameStatistics]; NSArray> *appStartSpans = sentryBuildAppStartSpans(self, appStartMeasurement); @@ -736,7 +736,7 @@ - (SentryTransaction *)toTransaction [spans addObjectsFromArray:_children]; } -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT [spans addObjectsFromArray:appStartSpans]; #endif // SENTRY_HAS_UIKIT @@ -763,7 +763,7 @@ - (SentryTransaction *)toTransaction [debugImageProvider getDebugImagesFromCacheForFrames:framesOfAllSpans]; } -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT [self addAppStartMeasurements:transaction]; if ([viewNames count] > 0) { @@ -774,7 +774,7 @@ - (SentryTransaction *)toTransaction return transaction; } -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT - (nullable SentryAppStartMeasurement *)getAppStartMeasurement SENTRY_DISABLE_THREAD_SANITIZER( "double-checked lock produce false alarms") diff --git a/Sources/Sentry/include/SentrySpan.h b/Sources/Sentry/include/SentrySpan.h index bcc9fba7459..b15dbe69428 100644 --- a/Sources/Sentry/include/SentrySpan.h +++ b/Sources/Sentry/include/SentrySpan.h @@ -96,7 +96,7 @@ SENTRY_NO_INIT */ - (instancetype)initWithTracer:(SentryTracer *)transaction context:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:(nullable SentryFramesTracker *)framesTracker; #endif // SENTRY_HAS_UIKIT ; @@ -106,7 +106,7 @@ SENTRY_NO_INIT * @param context This span context information. */ - (instancetype)initWithContext:(SentrySpanContext *)context -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:(nullable SentryFramesTracker *)framesTracker; #endif // SENTRY_HAS_UIKIT ; diff --git a/Tests/SentryTests/SentryClientTests.swift b/Tests/SentryTests/SentryClientTests.swift index 0559e9af90f..cf53f2b2f36 100644 --- a/Tests/SentryTests/SentryClientTests.swift +++ b/Tests/SentryTests/SentryClientTests.swift @@ -2531,7 +2531,7 @@ private extension SentryClientTests { } private func getSpan(operation: String, tracer: SentryTracer) -> Span { -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) return SentrySpan(tracer: tracer, context: SpanContext(operation: operation), framesTracker: nil) #else return SentrySpan(tracer: tracer, context: SpanContext(operation: operation)) diff --git a/Tests/SentryTests/SentryOptionsTest.m b/Tests/SentryTests/SentryOptionsTest.m index bb837bc1f98..df5790466fc 100644 --- a/Tests/SentryTests/SentryOptionsTest.m +++ b/Tests/SentryTests/SentryOptionsTest.m @@ -359,7 +359,7 @@ - (void)testBeforeSendSpan SentryOptions *options = [self getValidOptions:@{ @"beforeSendSpan" : callback }]; options.beforeSendSpan( [[SentrySpan alloc] initWithContext:[[SentrySpanContext alloc] initWithOperation:@""] -#if SENTRY_HAS_UIKIT && !TARGET_OS_VISION +#if SENTRY_HAS_UIKIT framesTracker:NULL #endif ]); diff --git a/Tests/SentryTests/Transaction/SentrySpanTests.swift b/Tests/SentryTests/Transaction/SentrySpanTests.swift index 476b597e28d..05d28282b4c 100644 --- a/Tests/SentryTests/Transaction/SentrySpanTests.swift +++ b/Tests/SentryTests/Transaction/SentrySpanTests.swift @@ -15,7 +15,7 @@ class SentrySpanTests: XCTestCase { let options: Options let notificationCenter = TestNSNotificationCenterWrapper() let currentDateProvider = TestCurrentDateProvider() -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) let tracer = SentryTracer(context: SpanContext(operation: "TEST"), framesTracker: nil) #else let tracer = SentryTracer(context: SpanContext(operation: "TEST")) @@ -41,7 +41,7 @@ class SentrySpanTests: XCTestCase { } func getSutWithTracer() -> SentrySpan { -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) return SentrySpan(tracer: tracer, context: SpanContext(operation: someOperation, sampled: .undecided), framesTracker: nil) #else return SentrySpan(tracer: tracer, context: SpanContext(operation: someOperation, sampled: .undecided)) @@ -538,7 +538,7 @@ class SentrySpanTests: XCTestCase { // Span has a weak reference to tracer. If we don't keep a reference // to the tracer ARC will deallocate the tracer. let sutGenerator: () -> Span = { -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) let tracer = SentryTracer(context: SpanContext(operation: "TEST"), framesTracker: nil) return SentrySpan(tracer: tracer, context: SpanContext(operation: ""), framesTracker: nil) #else From c647663c9d3bfd3d762dbd584c5cf794d7014873 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 10:20:18 +0100 Subject: [PATCH 09/12] update changelog and fix test conditions for UIKit and visionOS - Added entry to CHANGELOG for fixing `raw_description` in `runtime` context on Mac Catalyst. - Adjusted conditional compilation in various test files to improve compatibility with UIKit and visionOS. --- CHANGELOG.md | 1 + .../UIViewController/SentryTimeToDisplayTrackerTest.swift | 4 +--- Tests/SentryTests/PrivateSentrySDKOnlyTests.swift | 3 ++- Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift | 1 - Tests/SentryTests/SentryOptionsTest.m | 4 +++- .../Transaction/SentryBuildAppStartSpansTests.swift | 2 +- 6 files changed, 8 insertions(+), 7 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 91539b2e739..6318d6a1d21 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - Change default attributes of Logs to only include user attributes when `options.sendDefaultPii = true` (#7055) - Rename log attribute `sentry.trace.parent_span_id` to `span_id` (#7055) - Fixes stacktraces for MetricKit events (#6908) +- Fix `raw_description` in `runtime` context on Mac Catalyst (#7082) ## 9.1.0 diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift index 1de740e14cd..4bb1659e57f 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift @@ -3,11 +3,9 @@ import Foundation @_spi(Private) import SentryTestUtils import XCTest -#if !os(macOS) +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) class TestDelayedWrapper: SentryDelayedFramesTracker {} -#endif // !os(macOS) -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) class SentryTimeToDisplayTrackerTest: XCTestCase { private class Fixture { diff --git a/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift b/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift index 208583dbaa5..4c32132e003 100644 --- a/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift +++ b/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift @@ -447,6 +447,8 @@ class PrivateSentrySDKOnlyTests: XCTestCase { private func getFirstIntegrationAsReplay() throws -> SentrySessionReplayIntegration { return try XCTUnwrap(SentrySDKInternal.currentHub().installedIntegrations().first as? SentrySessionReplayIntegration) } + + private let VALID_REPLAY_ID = "0eac7ab503354dd5819b03e263627a29" #endif // SENTRY_TARGET_REPLAY_SUPPORTED func testAddExtraSdkPackages() throws { @@ -468,7 +470,6 @@ class PrivateSentrySDKOnlyTests: XCTestCase { } } - private let VALID_REPLAY_ID = "0eac7ab503354dd5819b03e263627a29" #endif private func getUnhandledExceptionEnvelope() -> SentryEnvelope { diff --git a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift index 378e8d12363..d1f34aaf6e2 100644 --- a/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift +++ b/Tests/SentryTests/SentryCrash/SentryCrashWrapperTests.swift @@ -1,5 +1,4 @@ @_spi(Private) @testable import Sentry -@_spi(Private) import SentryTestUtils import XCTest final class SentryCrashWrapperTests: XCTestCase { diff --git a/Tests/SentryTests/SentryOptionsTest.m b/Tests/SentryTests/SentryOptionsTest.m index df5790466fc..8c86b37dd1c 100644 --- a/Tests/SentryTests/SentryOptionsTest.m +++ b/Tests/SentryTests/SentryOptionsTest.m @@ -713,7 +713,7 @@ - (void)assertDefaultValues:(SentryOptions *)options XCTAssertEqual(200 * 1024 * 1024, options.maxAttachmentSize); XCTAssertEqual(NO, options.sendDefaultPii); XCTAssertTrue(options.enableAutoPerformanceTracing); -#if SENTRY_HAS_UIKIT && SENTRY_TARGET_REPLAY_SUPPORTED +#if SENTRY_HAS_UIKIT XCTAssertTrue(options.enableUIViewControllerTracing); XCTAssertFalse(options.attachScreenshot); XCTAssertEqual(3.0, options.idleTimeout); @@ -721,8 +721,10 @@ - (void)assertDefaultValues:(SentryOptions *)options XCTAssertEqual(options.enablePreWarmedAppStartTracing, YES); XCTAssertEqual(options.attachViewHierarchy, NO); XCTAssertEqual(options.reportAccessibilityIdentifier, YES); +# if SENTRY_TARGET_REPLAY_SUPPORTED XCTAssertEqual(options.sessionReplay.onErrorSampleRate, 0); XCTAssertEqual(options.sessionReplay.sessionSampleRate, 0); +# endif // SENTRY_TARGET_REPLAY_SUPPORTED #endif // SENTRY_HAS_UIKIT XCTAssertTrue(options.enableAppHangTracking); XCTAssertEqual(options.appHangTimeoutInterval, 2); diff --git a/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift b/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift index 31bd88407c3..b78bd129b3f 100644 --- a/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift +++ b/Tests/SentryTests/Transaction/SentryBuildAppStartSpansTests.swift @@ -1,7 +1,7 @@ @testable import Sentry import XCTest -#if canImport(UIKit) && !os(visionOS) +#if canImport(UIKit) class SentryBuildAppStartSpansTests: XCTestCase { func testSentryBuildAppStartSpans_appStartMeasurementIsNil_shouldNotReturnAnySpans() { From 8a930a0060dc21445a236ec307ffe13a7057fede Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 10:28:34 +0100 Subject: [PATCH 10/12] simplified conditional compilation --- .../Session/SentrySessionTrackerTests.swift | 22 +++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift index 0b64d5c8ee8..d54a98ef6cf 100644 --- a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift +++ b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift @@ -13,7 +13,7 @@ class SentrySessionTrackerTests: XCTestCase { let client: TestClient! let sentryCrash: TestSentryCrashWrapper - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) let _application: TestSentryUIApplication #else let _application: TestSentryNSApplication @@ -38,7 +38,7 @@ class SentrySessionTrackerTests: XCTestCase { sentryCrash = TestSentryCrashWrapper(processInfoWrapper: ProcessInfo.processInfo) - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) _application = TestSentryUIApplication() _application.unsafeApplicationState = .inactive #else @@ -537,7 +537,7 @@ class SentrySessionTrackerTests: XCTestCase { // MARK: - Helpers private func startSutInAppDelegate() { - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // The Sentry SDK should be initialized in the `UIAppDelegate.didFinishLaunchingWithOptions` // At this point the application state is `inactive`, because the app just launched but did not // become the active app yet. @@ -565,7 +565,7 @@ class SentrySessionTrackerTests: XCTestCase { // We remove the observers, to ensure future notifications are not handled. sut.removeObservers() - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // When the app stops, the app state is `inactive`. // This can be observed by viewing the application state in `UIAppDelegate.applicationDidEnterBackground`. fixture._application.unsafeApplicationState = .inactive @@ -580,7 +580,7 @@ class SentrySessionTrackerTests: XCTestCase { private func crashSut() { sut.removeObservers() - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // When the app stops, the app state is `inactive`. // // This can be observed by viewing the application state in `UIAppDelegate.applicationDidEnterBackground`. @@ -600,7 +600,7 @@ class SentrySessionTrackerTests: XCTestCase { } private func goToForeground() { - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // When the app becomes active, the app state is `active`. // This can be observed by viewing the application state in `UIAppDelegate.applicationDidBecomeActive`. fixture._application.unsafeApplicationState = .active @@ -622,7 +622,7 @@ class SentrySessionTrackerTests: XCTestCase { private func goToBackground() { // Before an app goes to background, it is still active and will resign from being active. willResignActive() - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // It is expected that the app state is background when the didEnterBackground is called fixture._application.unsafeApplicationState = .background fixture.notificationCenter @@ -642,7 +642,7 @@ class SentrySessionTrackerTests: XCTestCase { } private func willResignActive() { - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // When the app is about to resign being active, it is still active. // // This can be observed by viewing the application state in `UIAppDelegate.applicationWillResignActive`. @@ -665,7 +665,7 @@ class SentrySessionTrackerTests: XCTestCase { private func hybridSdkDidBecomeActive() { // When an app did become active, it is in the active state. - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) fixture._application.unsafeApplicationState = .active #else fixture._application.setIsActive(true) @@ -687,7 +687,7 @@ class SentrySessionTrackerTests: XCTestCase { } private func willTerminate() { - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) // When terminating an app, it will first move to the background and then terminate. // // This can be observed by viewing the application state in `UIAppDelegate.applicationWillTerminate`. @@ -876,7 +876,7 @@ class SentrySessionTrackerTests: XCTestCase { private func postHybridSdkDidBecomeActiveNotification() { // When the hybrid SDK posts this notification, the app should be in active state - #if (os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || (swift(>=5.9) && os(visionOS))) && !SENTRY_NO_UIKIT + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) fixture._application.unsafeApplicationState = .active #else fixture._application.setIsActive(true) From c1e3f817c715734f6bd1727c518a525d193dd647 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 10:59:45 +0100 Subject: [PATCH 11/12] fix: ensure test isolation in SentryTimeToDisplayTrackerTest Clear app start measurement in setUp() to prevent interference from previous tests that might have set it. This fixes a visionOS-specific test failure where testWaitingForFullDisplay_ReportFullDisplayBeforeInitialDisplay was failing when run with all tests due to incorrect tracer start timestamp. Also improve assertMeasurement helper to include file/line parameters for better test failure diagnostics. --- .../SentryTimeToDisplayTrackerTest.swift | 24 +++++++++++++++---- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift index 4bb1659e57f..058e84a0694 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift @@ -15,8 +15,13 @@ class SentryTimeToDisplayTrackerTest: XCTestCase { let framesTracker: SentryFramesTracker init() throws { - framesTracker = SentryFramesTracker(displayLinkWrapper: displayLinkWrapper, dateProvider: dateProvider, dispatchQueueWrapper: dispatchQueue, - notificationCenter: TestNSNotificationCenterWrapper(), delayedFramesTracker: TestDelayedWrapper(keepDelayedFramesDuration: 0, dateProvider: dateProvider)) + framesTracker = SentryFramesTracker( + displayLinkWrapper: displayLinkWrapper, + dateProvider: dateProvider, + dispatchQueueWrapper: dispatchQueue, + notificationCenter: TestNSNotificationCenterWrapper(), + delayedFramesTracker: TestDelayedWrapper(keepDelayedFramesDuration: 0, dateProvider: dateProvider) + ) SentryDependencyContainer.sharedInstance().framesTracker = framesTracker framesTracker.start() @@ -49,6 +54,9 @@ class SentryTimeToDisplayTrackerTest: XCTestCase { override func setUpWithError() throws { try super.setUpWithError() + // Ensure app start measurement is cleared before each test to avoid interference + // from previous tests that might have set it + SentrySDKInternal.setAppStartMeasurement(nil) fixture = try Fixture() } @@ -573,9 +581,15 @@ class SentryTimeToDisplayTrackerTest: XCTestCase { XCTAssertEqual(self.fixture.framesTracker.listenersCount, 0, "Frames tracker listener should be removed") } - private func assertMeasurement(tracer: SentryTracer, name: String, duration: TimeInterval) { - XCTAssertEqual(tracer.measurements[name]?.value, NSNumber(value: duration)) - XCTAssertEqual(tracer.measurements[name]?.unit?.unit, "millisecond") + private func assertMeasurement( + tracer: SentryTracer, + name: String, + duration: TimeInterval, + file: StaticString = #file, + line: UInt = #line + ) { + XCTAssertEqual(tracer.measurements[name]?.value, NSNumber(value: duration), file: file, line: line) + XCTAssertEqual(tracer.measurements[name]?.unit?.unit, "millisecond", file: file, line: line) } } From 9e863891acf1d6e9b51c31c6c0362c39a8bcac96 Mon Sep 17 00:00:00 2001 From: Philip Niedertscheider Date: Tue, 23 Dec 2025 11:56:38 +0100 Subject: [PATCH 12/12] change timeout of visionOS tests --- .github/workflows/test.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 8971aa2082d..5b83d1da618 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -247,7 +247,7 @@ jobs: xcode: ${{matrix.xcode}} platform: ${{matrix.platform}} test-destination-os: ${{matrix.test-destination-os || 'latest'}} - timeout: 20 + timeout: ${{matrix.timeout || 20}} device: ${{matrix.device || ''}} scheme: ${{matrix.scheme || 'Sentry'}} run_on_cirrus_labs: ${{ !contains(matrix.runs-on, 'macos-') }} @@ -377,6 +377,7 @@ jobs: test-destination-os: "26.1" platform: "visionOS" scheme: "Sentry" + timeout: 30 # This check validates that either all unit tests passed or were skipped, which allows us # to make unit tests a required check with only running the unit tests when required.