Skip to content

Commit

Permalink
RUM-7484 Add placeholder for unknown SwiftUI content
Browse files Browse the repository at this point in the history
  • Loading branch information
maxep committed Dec 18, 2024
1 parent 5a49e0f commit 3780aec
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 6 deletions.
4 changes: 4 additions & 0 deletions Datadog/Datadog.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -799,6 +799,7 @@
D20FD9D12ACC02F9004D3569 /* DatadogWebViewTracking.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3CE119FE29F7BE0100202522 /* DatadogWebViewTracking.framework */; };
D20FD9D32ACC08D1004D3569 /* WebKitMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FD9D22ACC08D1004D3569 /* WebKitMocks.swift */; };
D20FD9D62ACC0934004D3569 /* WebLogIntegrationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D20FD9D52ACC0934004D3569 /* WebLogIntegrationTests.swift */; };
D21331C12D132F0600E4A6A1 /* SwiftUIWireframesBuilderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D21331C02D132F0600E4A6A1 /* SwiftUIWireframesBuilderTests.swift */; };
D214DA8129DF2D5E004D0AE8 /* CrashReportingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DE333525C8278A008E3EC2 /* CrashReportingPlugin.swift */; };
D214DA8229DF2D5E004D0AE8 /* CrashReportingPlugin.swift in Sources */ = {isa = PBXBuildFile; fileRef = 61DE333525C8278A008E3EC2 /* CrashReportingPlugin.swift */; };
D214DA8329DF2D5E004D0AE8 /* CrashReporting.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6161247825CA9CA6009901BE /* CrashReporting.swift */; };
Expand Down Expand Up @@ -2869,6 +2870,7 @@
D20FD9CE2AC6FF42004D3569 /* WebViewLogReceiverTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebViewLogReceiverTests.swift; sourceTree = "<group>"; };
D20FD9D22ACC08D1004D3569 /* WebKitMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebKitMocks.swift; sourceTree = "<group>"; };
D20FD9D52ACC0934004D3569 /* WebLogIntegrationTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = WebLogIntegrationTests.swift; sourceTree = "<group>"; };
D21331C02D132F0600E4A6A1 /* SwiftUIWireframesBuilderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUIWireframesBuilderTests.swift; sourceTree = "<group>"; };
D213532F270CA722000315AD /* DataCompressionTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DataCompressionTests.swift; sourceTree = "<group>"; };
D214DAA429E072D7004D0AE8 /* MessageBus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MessageBus.swift; sourceTree = "<group>"; };
D214DAA729E54CB4004D0AE8 /* TelemetryReceiver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TelemetryReceiver.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -5733,6 +5735,7 @@
960B26BA2D03541900D7196F /* SwiftUI */ = {
isa = PBXGroup;
children = (
D21331C02D132F0600E4A6A1 /* SwiftUIWireframesBuilderTests.swift */,
962D72C42CF7806300F86EF0 /* GraphicsImageReflectionTests.swift */,
96867B982D08826B004AE0BC /* TextReflectionTests.swift */,
96867B9A2D0883DD004AE0BC /* ColorReflectionTests.swift */,
Expand Down Expand Up @@ -8606,6 +8609,7 @@
61054FC72A6EE1BA00AAA894 /* SRDataModelsMocks.swift in Sources */,
D218B0482D072CF300E3F82C /* SessionReplayTelemetryTests.swift in Sources */,
61054FC82A6EE1BA00AAA894 /* SnapshotProcessorSpy.swift in Sources */,
D21331C12D132F0600E4A6A1 /* SwiftUIWireframesBuilderTests.swift in Sources */,
A74A72872B10CE4100771FEB /* ResourceMocks.swift in Sources */,
61054FA42A6EE1BA00AAA894 /* DiffTests.swift in Sources */,
61054FA02A6EE1BA00AAA894 /* SRCompressionTests.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,12 @@ internal struct SwiftUIWireframesBuilder: NodeWireframesBuilder {
case .platformView:
return nil // Should be recorder by UIKit recorder
case .unknown:
return nil // Need a placeholder
return context.builder.createPlaceholderWireframe(
id: Int64(content.seed.value),
frame: context.convert(frame: item.frame),
clip: context.clip,
label: "Unsupported SwiftUI component"
)
}
}
}
Expand Down
12 changes: 7 additions & 5 deletions DatadogSessionReplay/Sources/Utilities/Reflector.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@ internal struct Reflector {

/// A `Lazy` reflection allows reflecting the subject at a later time.
struct Lazy<T> where T: Reflection {
private let reflector: Reflector
/// Relect to the type `T`.
let reflect: () throws -> T
}

private let mirror: ReflectionMirror
Expand Down Expand Up @@ -293,11 +294,12 @@ extension Reflection {

extension Reflector.Lazy: Reflection {
init(from reflector: Reflector) throws {
self.reflector = reflector
reflect = { try T(from: reflector) }
}
}

/// Relect to the type `T`.
func reflect() throws -> T {
try T(from: reflector)
extension Reflector.Lazy {
init(_ reflection: T) {
reflect = { reflection }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
* This product includes software developed at Datadog (https://www.datadoghq.com/).
* Copyright 2019-Present Datadog, Inc.
*/

import XCTest

#if os(iOS)
import XCTest
import SwiftUI
import DatadogInternal
import TestUtilities

@_spi(Internal)
@testable import DatadogSessionReplay

@available(iOS 13.0, tvOS 13.0, *)
class SwiftUIWireframesBuilderTests: XCTestCase {
func testDisplayListWithUnknownContent_itReturnsAPlaceholder() throws {
// Given
// - DisplayList with unknown content
let renderer = DisplayList.ViewUpdater(
viewCache: DisplayList.ViewUpdater.ViewCache(map: [:]),
lastList: DisplayList.Lazy(
DisplayList(items: [
DisplayList.Item(
identity: DisplayList.Identity(value: .mockRandom()),
frame: .mockAny(),
value: .content(DisplayList.Content(
seed: DisplayList.Seed(value: .mockRandom()),
value: .unknown
))
)
])
)
)

let builder = SwiftUIWireframesBuilder(
wireframeID: .mockRandom(),
renderer: renderer,
textObfuscator: TextObfuscatorMock(),
fontScalingEnabled: true,
imagePrivacyLevel: .maskNone,
attributes: .mockRandom()
)

// When
let wireframes = builder.buildWireframes(with: WireframesBuilder())

// Then
let wireframe = try XCTUnwrap(wireframes.last?.placeholderWireframe)
XCTAssertEqual(wireframe.label, "Unsupported SwiftUI component")
}
}

#endif

0 comments on commit 3780aec

Please sign in to comment.