@datadog/mobile-react-native-session-replay 2.6.0 → 2.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (36) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +52 -1
  3. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/DdSessionReplayImplementation.kt +5 -5
  4. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupport.kt +5 -29
  5. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/ShadowNodeWrapper.kt +2 -2
  6. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactEditTextMapper.kt +3 -26
  7. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/mappers/ReactTextMapper.kt +3 -25
  8. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/text/FabricTextViewUtils.kt +74 -0
  9. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/text/LegacyTextViewUtils.kt +118 -0
  10. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/{ReactTextPropertiesResolver.kt → utils/text/TextViewUtils.kt} +60 -96
  11. package/android/src/rn75/kotlin/com/datadog/reactnative/sessionreplay/extensions/LengthPercentageExt.kt +1 -2
  12. package/android/src/rn75/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt +1 -3
  13. package/android/src/rn76/kotlin/com/datadog/reactnative/sessionreplay/extensions/LengthPercentageExt.kt +1 -1
  14. package/android/src/rn76/kotlin/com/datadog/reactnative/sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt +1 -3
  15. package/android/src/rnlegacy/kotlin/com.datadog.reactnative.sessionreplay/utils/ReactViewBackgroundDrawableUtils.kt +2 -7
  16. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/ReactNativeSessionReplayExtensionSupportTest.kt +3 -17
  17. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/{ReactTextPropertiesResolverTest.kt → utils/text/TextViewUtilsTest.kt} +171 -38
  18. package/ios/Sources/DdSessionReplay.mm +4 -4
  19. package/ios/Sources/DdSessionReplayImplementation.swift +13 -3
  20. package/ios/Sources/RCTFabricWrapper.h +13 -0
  21. package/ios/Sources/RCTFabricWrapper.mm +120 -0
  22. package/ios/Sources/RCTTextPropertiesWrapper.h +23 -0
  23. package/ios/Sources/RCTTextPropertiesWrapper.mm +28 -0
  24. package/ios/Sources/RCTTextViewRecorder.swift +69 -49
  25. package/ios/Sources/RCTVersion.h +8 -0
  26. package/lib/commonjs/SessionReplay.js +1 -1
  27. package/lib/commonjs/SessionReplay.js.map +1 -1
  28. package/lib/module/SessionReplay.js +1 -1
  29. package/lib/module/SessionReplay.js.map +1 -1
  30. package/package.json +6 -3
  31. package/scripts/set-ios-rn-version.js +47 -0
  32. package/src/SessionReplay.ts +1 -1
  33. package/src/__tests__/SessionReplay.test.ts +1 -1
  34. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/NoopTextPropertiesResolver.kt +0 -22
  35. package/android/src/main/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtils.kt +0 -40
  36. package/android/src/test/kotlin/com/datadog/reactnative/sessionreplay/utils/TextViewUtilsTest.kt +0 -109
@@ -0,0 +1,118 @@
1
+ package com.datadog.reactnative.sessionreplay.utils.text
2
+
3
+ import android.widget.TextView
4
+ import androidx.annotation.VisibleForTesting
5
+ import com.datadog.android.api.InternalLogger
6
+ import com.datadog.android.internal.utils.densityNormalized
7
+ import com.datadog.android.sessionreplay.model.MobileSegment
8
+ import com.datadog.reactnative.sessionreplay.ShadowNodeWrapper
9
+ import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
10
+ import com.datadog.reactnative.sessionreplay.utils.ReflectionUtils
11
+ import com.datadog.reactnative.sessionreplay.utils.formatAsRgba
12
+ import com.facebook.react.bridge.ReactContext
13
+ import com.facebook.react.uimanager.UIManagerModule
14
+ import com.facebook.react.views.text.TextAttributes
15
+ import java.util.Locale
16
+
17
+ internal class LegacyTextViewUtils(
18
+ private val reactContext: ReactContext,
19
+ private val logger: InternalLogger,
20
+ private val reflectionUtils: ReflectionUtils,
21
+ drawableUtils: DrawableUtils,
22
+ ) : TextViewUtils(reactContext, drawableUtils) {
23
+
24
+ private val uiManager: UIManagerModule? by lazy {
25
+ getUiManagerModule()
26
+ }
27
+
28
+ override fun resolveTextStyle(
29
+ textWireframe: MobileSegment.Wireframe.TextWireframe,
30
+ pixelsDensity: Float,
31
+ view: TextView,
32
+ ): MobileSegment.TextStyle? {
33
+ val shadowNodeWrapper: ShadowNodeWrapper =
34
+ ShadowNodeWrapper.getShadowNodeWrapper(
35
+ reactContext = reactContext,
36
+ uiManagerModule = uiManager,
37
+ reflectionUtils = reflectionUtils,
38
+ viewId = view.id,
39
+ ) ?: return null
40
+
41
+ val fontFamily = getFontFamily(shadowNodeWrapper) ?: textWireframe.textStyle.family
42
+
43
+ val fontSize = getFontSize(shadowNodeWrapper)?.densityNormalized(pixelsDensity) ?: textWireframe.textStyle.size
44
+
45
+ val fontColor = getTextColor(shadowNodeWrapper) ?: textWireframe.textStyle.color
46
+
47
+ return MobileSegment.TextStyle(
48
+ family = fontFamily,
49
+ size = fontSize,
50
+ color = fontColor,
51
+ )
52
+ }
53
+
54
+ private fun getTextColor(shadowNodeWrapper: ShadowNodeWrapper?): String? {
55
+ if (shadowNodeWrapper == null) return null
56
+
57
+ val isColorSet =
58
+ shadowNodeWrapper
59
+ .getDeclaredShadowNodeField(IS_COLOR_SET_FIELD_NAME) as Boolean?
60
+
61
+ if (isColorSet != true) {
62
+ // Improvement: get default text color if different from black
63
+ return "#000000FF"
64
+ }
65
+ val resolvedColor =
66
+ shadowNodeWrapper
67
+ .getDeclaredShadowNodeField(COLOR_FIELD_NAME) as Int?
68
+ if (resolvedColor != null) {
69
+ return formatAsRgba(resolvedColor)
70
+ }
71
+
72
+ return null
73
+ }
74
+
75
+ private fun getFontSize(shadowNodeWrapper: ShadowNodeWrapper?): Long? {
76
+ if (shadowNodeWrapper == null) return null
77
+
78
+ val textAttributes =
79
+ shadowNodeWrapper
80
+ .getDeclaredShadowNodeField(TEXT_ATTRIBUTES_FIELD_NAME) as? TextAttributes?
81
+ if (textAttributes != null) {
82
+ return textAttributes.effectiveFontSize.toLong()
83
+ }
84
+
85
+ return null
86
+ }
87
+
88
+ private fun getFontFamily(shadowNodeWrapper: ShadowNodeWrapper?): String? {
89
+ if (shadowNodeWrapper == null) return null
90
+
91
+ val fontFamily =
92
+ shadowNodeWrapper
93
+ .getDeclaredShadowNodeField(FONT_FAMILY_FIELD_NAME) as? String
94
+
95
+ if (fontFamily != null) {
96
+ return resolveFontFamily(fontFamily.lowercase(Locale.US))
97
+ }
98
+
99
+ return null
100
+ }
101
+
102
+ // store to avoid calling it multiple times
103
+ @VisibleForTesting
104
+ internal fun getUiManagerModule(): UIManagerModule? {
105
+ return try {
106
+ reactContext.getNativeModule(UIManagerModule::class.java)
107
+ } catch (e: IllegalStateException) {
108
+ logger.log(
109
+ level = InternalLogger.Level.WARN,
110
+ targets = listOf(InternalLogger.Target.MAINTAINER, InternalLogger.Target.TELEMETRY),
111
+ messageBuilder = { RESOLVE_UIMANAGERMODULE_ERROR },
112
+ throwable = e,
113
+ )
114
+ return null
115
+ }
116
+ }
117
+ }
118
+
@@ -1,33 +1,42 @@
1
- /*
2
- * Unless explicitly stated otherwise all files in this repository are licensed under the Apache License Version 2.0.
3
- * This product includes software developed at Datadog (https://www.datadoghq.com/).
4
- * Copyright 2016-Present Datadog, Inc.
5
- */
6
-
7
- package com.datadog.reactnative.sessionreplay
1
+ package com.datadog.reactnative.sessionreplay.utils.text
8
2
 
9
3
  import ReactViewBackgroundDrawableUtils
10
4
  import android.view.Gravity
11
5
  import android.widget.TextView
12
6
  import androidx.annotation.VisibleForTesting
13
- import com.datadog.android.internal.utils.densityNormalized
7
+ import com.datadog.android.api.InternalLogger
14
8
  import com.datadog.android.sessionreplay.model.MobileSegment
9
+ import com.datadog.android.sessionreplay.recorder.MappingContext
10
+ import com.datadog.reactnative.sessionreplay.BuildConfig
15
11
  import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
16
12
  import com.datadog.reactnative.sessionreplay.utils.ReflectionUtils
17
- import com.datadog.reactnative.sessionreplay.utils.formatAsRgba
18
13
  import com.facebook.react.bridge.ReactContext
19
- import com.facebook.react.uimanager.UIManagerModule
20
- import com.facebook.react.views.text.TextAttributes
21
- import java.util.Locale
22
-
23
- internal class ReactTextPropertiesResolver(
24
- private val reactContext: ReactContext,
25
- private val uiManagerModule: UIManagerModule,
26
- private val reflectionUtils: ReflectionUtils = ReflectionUtils(),
27
- private val drawableUtils: DrawableUtils =
28
- ReactViewBackgroundDrawableUtils()
29
- ): TextPropertiesResolver {
30
- override fun addReactNativeProperties(
14
+
15
+ internal abstract class TextViewUtils(private val reactContext: ReactContext, private val drawableUtils: DrawableUtils) {
16
+ fun mapTextViewToWireframes(
17
+ wireframes: List<MobileSegment.Wireframe>,
18
+ view: TextView,
19
+ mappingContext: MappingContext,
20
+ ): List<MobileSegment.Wireframe> {
21
+ val result = mutableListOf<MobileSegment.Wireframe>()
22
+ val pixelDensity = mappingContext.systemInformation.screenDensity
23
+
24
+ for (originalWireframe in wireframes) {
25
+ if (originalWireframe !is MobileSegment.Wireframe.TextWireframe) {
26
+ result.add(originalWireframe)
27
+ } else {
28
+ result.add(addReactNativeProperties(
29
+ originalWireframe = originalWireframe,
30
+ view = view,
31
+ pixelDensity = pixelDensity,
32
+ ))
33
+ }
34
+ }
35
+
36
+ return result
37
+ }
38
+
39
+ fun addReactNativeProperties(
31
40
  originalWireframe: MobileSegment.Wireframe.TextWireframe,
32
41
  view: TextView,
33
42
  pixelDensity: Float,
@@ -59,25 +68,17 @@ internal class ReactTextPropertiesResolver(
59
68
  )
60
69
  }
61
70
 
62
- private fun resolveTextStyleAndPosition(
71
+
72
+ protected fun resolveTextStyleAndPosition(
63
73
  originalWireframe: MobileSegment.Wireframe.TextWireframe,
64
74
  view: TextView,
65
- pixelDensity: Float,
66
- ):
67
- Pair<MobileSegment.TextStyle, MobileSegment.TextPosition>? {
68
-
75
+ pixelDensity: Float
76
+ ): Pair<MobileSegment.TextStyle, MobileSegment.TextPosition>? {
69
77
  if (!reactContext.hasActiveReactInstance()) {
70
78
  return null
71
79
  }
72
80
 
73
- val shadowNodeWrapper: ShadowNodeWrapper =
74
- ShadowNodeWrapper.getShadowNodeWrapper(
75
- reactContext = reactContext,
76
- uiManagerModule = uiManagerModule,
77
- reflectionUtils = reflectionUtils,
78
- viewId = view.id) ?: return null
79
-
80
- val textStyle = resolveTextStyle(originalWireframe, pixelDensity, shadowNodeWrapper)
81
+ val textStyle = resolveTextStyle(originalWireframe, pixelDensity, view) ?: return null
81
82
  val alignment = resolveTextAlignment(view, originalWireframe)
82
83
 
83
84
  val textPosition = MobileSegment.TextPosition(
@@ -88,7 +89,7 @@ internal class ReactTextPropertiesResolver(
88
89
  return textStyle to textPosition
89
90
  }
90
91
 
91
- private fun resolveShapeStyleAndBorder(
92
+ protected fun resolveShapeStyleAndBorder(
92
93
  view: TextView,
93
94
  pixelDensity: Float,
94
95
  ): Pair<MobileSegment.ShapeStyle?, MobileSegment.ShapeBorder?>? {
@@ -105,7 +106,7 @@ internal class ReactTextPropertiesResolver(
105
106
  return shapeStyle to border
106
107
  }
107
108
 
108
- private fun resolveTextAlignment(
109
+ protected fun resolveTextAlignment(
109
110
  view: TextView,
110
111
  textWireframe: MobileSegment.Wireframe.TextWireframe
111
112
  ): MobileSegment.Alignment {
@@ -126,64 +127,7 @@ internal class ReactTextPropertiesResolver(
126
127
  )
127
128
  }
128
129
 
129
- private fun resolveTextStyle(
130
- textWireframe: MobileSegment.Wireframe.TextWireframe,
131
- pixelsDensity: Float,
132
- shadowNodeWrapper: ShadowNodeWrapper
133
- ): MobileSegment.TextStyle {
134
- val fontFamily = getFontFamily(shadowNodeWrapper)
135
- ?: textWireframe.textStyle.family
136
- val fontSize = getFontSize(shadowNodeWrapper)
137
- ?.densityNormalized(pixelsDensity)
138
- ?: textWireframe.textStyle.size
139
- val fontColor = getTextColor(shadowNodeWrapper)
140
- ?: textWireframe.textStyle.color
141
-
142
- return MobileSegment.TextStyle(
143
- family = fontFamily,
144
- size = fontSize,
145
- color = fontColor
146
- )
147
- }
148
-
149
- private fun getTextColor(shadowNodeWrapper: ShadowNodeWrapper): String? {
150
- val isColorSet = shadowNodeWrapper
151
- .getDeclaredShadowNodeField(IS_COLOR_SET_FIELD_NAME) as Boolean?
152
- if (isColorSet != true) {
153
- // Improvement: get default text color if different from black
154
- return "#000000FF"
155
- }
156
- val resolvedColor = shadowNodeWrapper
157
- .getDeclaredShadowNodeField(COLOR_FIELD_NAME) as Int?
158
- if (resolvedColor != null) {
159
- return formatAsRgba(resolvedColor)
160
- }
161
-
162
- return null
163
- }
164
-
165
- private fun getFontSize(shadowNodeWrapper: ShadowNodeWrapper): Long? {
166
- val textAttributes = shadowNodeWrapper
167
- .getDeclaredShadowNodeField(TEXT_ATTRIBUTES_FIELD_NAME) as? TextAttributes?
168
- if (textAttributes != null) {
169
- return textAttributes.effectiveFontSize.toLong()
170
- }
171
-
172
- return null
173
- }
174
-
175
- private fun getFontFamily(shadowNodeWrapper: ShadowNodeWrapper): String? {
176
- val fontFamily = shadowNodeWrapper
177
- .getDeclaredShadowNodeField(FONT_FAMILY_FIELD_NAME) as? String
178
-
179
- if (fontFamily != null) {
180
- return resolveFontFamily(fontFamily.lowercase(Locale.US))
181
- }
182
-
183
- return null
184
- }
185
-
186
- private fun resolveFontFamily(typefaceName: String): String =
130
+ protected fun resolveFontFamily(typefaceName: String): String =
187
131
  when (typefaceName) {
188
132
  ROBOTO_TYPEFACE_NAME -> SANS_SERIF_FAMILY_NAME
189
133
  MONOSPACE_FAMILY_NAME -> MONOSPACE_FAMILY_NAME
@@ -191,16 +135,36 @@ internal class ReactTextPropertiesResolver(
191
135
  else -> SANS_SERIF_FAMILY_NAME
192
136
  }
193
137
 
138
+ protected abstract fun resolveTextStyle( textWireframe: MobileSegment.Wireframe.TextWireframe,
139
+ pixelsDensity: Float,
140
+ view: TextView
141
+ ): MobileSegment.TextStyle?
142
+
194
143
  @VisibleForTesting
195
- internal companion object {
144
+ companion object {
196
145
  internal const val TEXT_ATTRIBUTES_FIELD_NAME = "mTextAttributes"
197
146
  internal const val FONT_FAMILY_FIELD_NAME = "mFontFamily"
198
147
  internal const val COLOR_FIELD_NAME = "mColor"
199
148
  internal const val IS_COLOR_SET_FIELD_NAME = "mIsColorSet"
149
+ internal const val SPANNED_FIELD_NAME = "mSpanned"
200
150
 
201
151
  private const val ROBOTO_TYPEFACE_NAME = "roboto"
202
152
  private const val SERIF_FAMILY_NAME = "serif"
203
153
  private const val SANS_SERIF_FAMILY_NAME = "roboto, sans-serif"
204
154
  internal const val MONOSPACE_FAMILY_NAME = "monospace"
155
+
156
+
157
+ internal const val RESOLVE_UIMANAGERMODULE_ERROR = "Unable to resolve UIManagerModule"
158
+ internal const val RESOLVE_FABRICFIELD_ERROR = "Unable to resolve field from fabric view"
159
+ internal const val NULL_FABRICFIELD_ERROR = "Null value found when trying to resolve field from fabric view"
160
+
161
+
162
+ fun create(reactContext: ReactContext, logger: InternalLogger): TextViewUtils {
163
+ return when (BuildConfig.IS_NEW_ARCHITECTURE_ENABLED) {
164
+ true -> FabricTextViewUtils(reactContext, logger, ReactViewBackgroundDrawableUtils())
165
+ false -> LegacyTextViewUtils(reactContext, logger, ReflectionUtils(), ReactViewBackgroundDrawableUtils())
166
+ }
167
+ }
205
168
  }
206
- }
169
+
170
+ }
@@ -9,5 +9,4 @@ import com.facebook.react.uimanager.LengthPercentage
9
9
 
10
10
  internal fun LengthPercentage?.getRadius(width: Float, height: Float) = this
11
11
  ?.resolve(width, height)
12
- ?.let { (it.horizontal + it.vertical) / 2f }
13
- ?: 0f
12
+ ?: 0f
@@ -6,7 +6,6 @@
6
6
  import android.graphics.drawable.Drawable
7
7
  import android.graphics.drawable.InsetDrawable
8
8
  import android.graphics.drawable.LayerDrawable
9
- import com.datadog.android.internal.utils.densityNormalized
10
9
  import com.datadog.android.sessionreplay.model.MobileSegment
11
10
  import com.datadog.reactnative.sessionreplay.extensions.getRadius
12
11
  import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
@@ -85,8 +84,7 @@ internal class ReactViewBackgroundDrawableUtils : DrawableUtils() {
85
84
  backgroundDrawable: CSSBackgroundDrawable,
86
85
  pixelDensity: Float
87
86
  ): MobileSegment.ShapeBorder {
88
- val borderWidth =
89
- backgroundDrawable.fullBorderWidth.toLong().densityNormalized(pixelDensity)
87
+ val borderWidth = (backgroundDrawable.fullBorderWidth / pixelDensity).toLong()
90
88
  val borderColor = formatAsRgba(backgroundDrawable.getBorderColor(Spacing.ALL))
91
89
 
92
90
  return MobileSegment.ShapeBorder(
@@ -10,4 +10,4 @@ import com.facebook.react.uimanager.LengthPercentage
10
10
  internal fun LengthPercentage?.getRadius(width: Float, height: Float) = this
11
11
  ?.resolve(width, height)
12
12
  ?.let { (it.horizontal + it.vertical) / 2f }
13
- ?: 0f
13
+ ?: 0f
@@ -6,7 +6,6 @@
6
6
  import android.graphics.drawable.Drawable
7
7
  import android.graphics.drawable.InsetDrawable
8
8
  import android.graphics.drawable.LayerDrawable
9
- import com.datadog.android.internal.utils.densityNormalized
10
9
  import com.datadog.android.sessionreplay.model.MobileSegment
11
10
  import com.datadog.reactnative.sessionreplay.extensions.getRadius
12
11
  import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
@@ -85,8 +84,7 @@ internal class ReactViewBackgroundDrawableUtils : DrawableUtils() {
85
84
  backgroundDrawable: CSSBackgroundDrawable,
86
85
  pixelDensity: Float
87
86
  ): MobileSegment.ShapeBorder {
88
- val borderWidth =
89
- backgroundDrawable.fullBorderWidth.toLong().densityNormalized(pixelDensity)
87
+ val borderWidth = (backgroundDrawable.fullBorderWidth / pixelDensity).toLong()
90
88
  val borderColor = formatAsRgba(backgroundDrawable.getBorderColor(Spacing.ALL))
91
89
 
92
90
  return MobileSegment.ShapeBorder(
@@ -1,7 +1,6 @@
1
1
  import android.graphics.drawable.Drawable
2
2
  import android.graphics.drawable.InsetDrawable
3
3
  import android.graphics.drawable.LayerDrawable
4
- import com.datadog.android.internal.utils.densityNormalized
5
4
  import com.datadog.android.sessionreplay.model.MobileSegment
6
5
  import com.datadog.reactnative.sessionreplay.utils.DrawableUtils
7
6
  import com.datadog.reactnative.sessionreplay.utils.formatAsRgba
@@ -19,10 +18,7 @@ internal class ReactViewBackgroundDrawableUtils() : DrawableUtils() {
19
18
  }
20
19
 
21
20
  val borderProps = resolveBorder(drawable, pixelDensity)
22
- val cornerRadius = drawable
23
- .fullBorderRadius
24
- .toLong()
25
- .densityNormalized(pixelDensity)
21
+ val cornerRadius = (drawable.fullBorderRadius / pixelDensity).toLong()
26
22
 
27
23
  val backgroundColor = getBackgroundColor(drawable)
28
24
  val colorHexString = if (backgroundColor != null) {
@@ -63,8 +59,7 @@ internal class ReactViewBackgroundDrawableUtils() : DrawableUtils() {
63
59
  backgroundDrawable: ReactViewBackgroundDrawable,
64
60
  pixelDensity: Float
65
61
  ): MobileSegment.ShapeBorder {
66
- val borderWidth =
67
- backgroundDrawable.fullBorderWidth.toLong().densityNormalized(pixelDensity)
62
+ val borderWidth = (backgroundDrawable.fullBorderWidth / pixelDensity).toLong()
68
63
  val borderColor = formatAsRgba(backgroundDrawable.getBorderColor(Spacing.ALL))
69
64
 
70
65
  return MobileSegment.ShapeBorder(
@@ -11,6 +11,7 @@ import com.datadog.reactnative.sessionreplay.mappers.ReactEditTextMapper
11
11
  import com.datadog.reactnative.sessionreplay.mappers.ReactNativeImageViewMapper
12
12
  import com.datadog.reactnative.sessionreplay.mappers.ReactTextMapper
13
13
  import com.datadog.reactnative.sessionreplay.mappers.ReactViewGroupMapper
14
+ import com.datadog.reactnative.sessionreplay.utils.text.TextViewUtils
14
15
  import com.facebook.react.bridge.NativeModule
15
16
  import com.facebook.react.bridge.ReactContext
16
17
  import com.facebook.react.uimanager.UIManagerModule
@@ -51,10 +52,8 @@ internal class ReactNativeSessionReplayExtensionSupportTest {
51
52
  whenever(mockReactContext.getNativeModule(any<Class<NativeModule>>()))
52
53
  .doReturn(mockUiManagerModule)
53
54
 
54
- testedExtensionSupport = ReactNativeSessionReplayExtensionSupport(
55
- logger = mockLogger,
56
- reactContext = mockReactContext
57
- )
55
+ val textViewUtils = TextViewUtils.create(mockReactContext, mockLogger)
56
+ testedExtensionSupport = ReactNativeSessionReplayExtensionSupport(textViewUtils)
58
57
  }
59
58
 
60
59
  @Test
@@ -77,17 +76,4 @@ internal class ReactNativeSessionReplayExtensionSupportTest {
77
76
  assertThat(customViewMappers[3].getUnsafeMapper())
78
77
  .isInstanceOf(ReactEditTextMapper::class.java)
79
78
  }
80
-
81
- @Test
82
- fun `M return null W getUiManagerModule() { cannot get uiManagerModule }`() {
83
- // Given
84
- whenever(mockReactContext.getNativeModule(any<Class<NativeModule>>()))
85
- .thenThrow(IllegalStateException())
86
-
87
- // When
88
- val uiManagerModule = testedExtensionSupport.getUiManagerModule()
89
-
90
- // Then
91
- assertThat(uiManagerModule).isNull()
92
- }
93
79
  }