-
Notifications
You must be signed in to change notification settings - Fork 63
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RUMM-2777 SR add dialogs recording support #1206
RUMM-2777 SR add dialogs recording support #1206
Conversation
823cabb
to
fb96550
Compare
fb96550
to
6c6dc8c
Compare
Codecov Report
@@ Coverage Diff @@
## feature/sdkv2 #1206 +/- ##
=================================================
+ Coverage 82.59% 82.61% +0.02%
=================================================
Files 351 353 +2
Lines 12480 12537 +57
Branches 2058 2075 +17
=================================================
+ Hits 10307 10357 +50
- Misses 1533 1539 +6
- Partials 640 641 +1
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lgtm! I've added some comments, but they are non-blocking.
recorder.startRecording(windows, ownerActivity) | ||
recordCallback.onStartRecording() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: It seems in the code recorder.startRecording
is always followed by the recordCallback.onStartRecording
(same for the stop
sequence). Does it make sense to put recordCallback
inside recorder
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good point, let me check
@@ -65,43 +81,63 @@ class SessionReplayLifecycleCallbackTest { | |||
} | |||
|
|||
@Test | |||
fun `M start recording activity W onActivityResumed()`() { | |||
fun `M start register fragment lifecycle W onActivityCreated(){FragmentActivity}`() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fun `M start register fragment lifecycle W onActivityCreated(){FragmentActivity}`() { | |
fun `M register fragment lifecycle W onActivityCreated(){FragmentActivity}`() { |
// When | ||
testedCallback.onActivityResumed(mockActivity) | ||
|
||
// Then | ||
verify(mockRecoder).startRecording(mockActivity) | ||
assertThat(testedCallback.resumedActivities).containsKey(mockActivity) | ||
verify(mockRecoder).startRecording(eq(listOf(mockWindow)), eq(mockActivity)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
minor: eq
calls are not needed here and in some tests below as well, they are only needed when one of the arguments is capture()
call.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You are right, reason why I added those like that was cause I thought it will do the assertion by reference in cause of the lists. Apparently is doing it by value anyway without the eq
@@ -1,4 +1,4 @@ | |||
/* | |||
/* |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
seems like redundant change
it.decorView.viewTreeObserver.inOrder { | ||
verify().addOnDrawListener(captor.capture()) | ||
verify().removeOnDrawListener(captor.firstValue) | ||
verify().addOnDrawListener(captor.capture()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we don't assert the result of the 2nd capture
call, is it expected?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes because as the test is saying I just want to test that the previously registered windows (first call) were un - registered.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, just semantically on this line we capture something what we don't use later, so maybe the cleaner thing will be something like verify().addOnDrawListener(any())
val mockViewTreeObserver: ViewTreeObserver = mock() | ||
val mockActivity = mockActivity(forge, mockViewTreeObserver) | ||
testedRecorder.startRecording(mockActivity) | ||
val fakeWindowsActivityPairs: List<Pair<List<Window>, Activity>> = forge.aList { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
kotlin cannot infer the type here? given that types of aMockedWindowsList()
and aMockedActivity()
are known.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let me check
4203c9f
to
dfe5da8
Compare
import android.os.Build | ||
import android.view.MotionEvent | ||
|
||
internal class MotionEventUtils { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems like this could be an object
, or just an ensemble of extension fun
on MotionEvent
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I will make it an object, I don't like extensions as they are making your life harder when you have to mock them.
} | ||
} | ||
|
||
private fun Fragment.asValidDialogFragment(): DialogFragment? { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It seems all usage of this method are followed by ?.let { … }
, you could make this method look like this:
fun Fragment.asValidDialogFragment(block:(DialogFragment) ->) {
if (this is DialogFragment && context != null) {
block(this)
}
}
dd-sdk-android/src/test/kotlin/com/datadog/android/v2/core/DatadogCoreTest.kt
Show resolved
Hide resolved
it.decorView.viewTreeObserver.inOrder { | ||
verify().addOnDrawListener(captor.capture()) | ||
verify().removeOnDrawListener(captor.firstValue) | ||
verify().addOnDrawListener(captor.capture()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes, just semantically on this line we capture something what we don't use later, so maybe the cleaner thing will be something like verify().addOnDrawListener(any())
verify(mockViewTreeObserver).addOnDrawListener(captor.capture()) | ||
verify(mockViewTreeObserver).removeOnDrawListener(captor.firstValue) | ||
fakeWindowsActivityPairs.map { it.first }.flatten().forEach { | ||
val captor = argumentCaptor<ViewTreeObserver.OnDrawListener>() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need captor here, because we don't run any assertions on the values captured. We can use simply verify().addOnDrawListener(any())
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
well actually I am doing it here:
verify(it.decorView.viewTreeObserver).removeOnDrawListener(captor.firstValue)
. I know it could work with any
too but I would rather use an explicit verification.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nevermind, you are right, I was looking at the wrong line actually.
dfe5da8
to
cb91a83
Compare
What does this PR do?
We were currently not recording the
DialogFragment
(pop - ups) for session replay. In this PR we are adding this new feature which implies the following architectural changes:ScreenRecorder
will now be able to record multiple windows in the same time with the sameownerActivity
. This actually covers the case of aDialogFragment
.SnapshotProcessor
will be able to handle a list ofsnapshots
now instead of onesingle snapshot
at a time.I also addressed a bug in this PR : we were not using the
MotionEvent
absolute X,Y positions when recording the user gestures for Session Replay.Motivation
What inspired you to submit this pull request?
Additional Notes
Anything else we should know when reviewing?
Review checklist (to be filled by reviewers)