diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 16d51b972d..5b83d1da61 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-') }} @@ -370,6 +370,15 @@ 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" + 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. # So, we don't have to run unit tests, for example, for Changelog or ReadMe changes. diff --git a/SentryTestUtils/Headers/SentryTestUtils-ObjC-BridgingHeader.h b/SentryTestUtils/Headers/SentryTestUtils-ObjC-BridgingHeader.h index 8b541de219..8e155820bb 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 54f207e54e..81f75a33f9 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/Tests/SentryTests/Helper/SentryDeviceTests.m b/Tests/SentryTests/Helper/SentryDeviceTests.m index e71c1528f2..cd69d2ad2f 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 b4250affb7..32940e92e3 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 81a9cc49ee..058e84a069 100644 --- a/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift +++ b/Tests/SentryTests/Integrations/Performance/UIViewController/SentryTimeToDisplayTrackerTest.swift @@ -3,8 +3,7 @@ import Foundation @_spi(Private) import SentryTestUtils import XCTest -#if os(iOS) || os(tvOS) || targetEnvironment(macCatalyst) - +#if os(iOS) || os(tvOS) || os(visionOS) || targetEnvironment(macCatalyst) class TestDelayedWrapper: SentryDelayedFramesTracker {} class SentryTimeToDisplayTrackerTest: XCTestCase { @@ -16,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() @@ -50,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() } @@ -574,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) } } diff --git a/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift b/Tests/SentryTests/Integrations/Session/SentrySessionTrackerTests.swift index c0078e64d2..d54a98ef6c 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) || 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) + #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) + #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) + #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) + #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) + #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) + #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) + #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) + #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) + #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) + #if os(iOS) || targetEnvironment(macCatalyst) || os(tvOS) || os(visionOS) fixture._application.unsafeApplicationState = .active #else fixture._application.setIsActive(true) diff --git a/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift b/Tests/SentryTests/PrivateSentrySDKOnlyTests.swift index 3ea98fa28e..4c32132e00 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,13 @@ class PrivateSentrySDKOnlyTests: XCTestCase { XCTAssertTrue(redactBuilder.isRedactContainerClassTestOnly(RedactContainer.self)) } + 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 { PrivateSentrySDKOnly.addSdkPackage("package1", version: "version1") PrivateSentrySDKOnly.addSdkPackage("package2", version: "version2") @@ -462,11 +470,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 private func getUnhandledExceptionEnvelope() -> SentryEnvelope { diff --git a/Tests/SentryTests/Protocol/TestData.swift b/Tests/SentryTests/Protocol/TestData.swift index e9aff3b881..2da2e043ab 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 06876f5626..cf53f2b2f3 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) @@ -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 9ca5afb041..8c86b37dd1 100644 --- a/Tests/SentryTests/SentryOptionsTest.m +++ b/Tests/SentryTests/SentryOptionsTest.m @@ -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); @@ -893,6 +895,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 +915,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 ec65dd6fa7..ef124c49ca 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 b5ebf4c6a6..0f2dfb558f 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 acf4e0ba5c..888bb80f5d 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/SentrySpanTests.swift b/Tests/SentryTests/Transaction/SentrySpanTests.swift index 476b597e28..05d28282b4 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 diff --git a/Tests/SentryTests/Transaction/SentryTracerTests.swift b/Tests/SentryTests/Transaction/SentryTracerTests.swift index bc001e564e..2c06ea4a7d 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 1b92c573f3..f8292ac7ac 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) diff --git a/scripts/sentry-xcodebuild.sh b/scripts/sentry-xcodebuild.sh index 2707fd7712..ac14603f5a 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