Skip to content

Commit 91a97d6

Browse files
ahmedAlaaInstabugmzelzoghbi
authored andcommitted
feat: add get session replay link API (#1142)
Jira ID: MOB-14010
1 parent d452631 commit 91a97d6

File tree

13 files changed

+139
-0
lines changed

13 files changed

+139
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
### Added
66

7+
- Add `SessionReplay.getSessionReplayLink` API which retrieves the current session's replay link ([#1142](https://github.com/Instabug/Instabug-React-Native/pull/1142)).
78
- Support setting the Code Push version after SDK initialization ([#1143](https://github.com/Instabug/Instabug-React-Native/pull/1143)).
89

910
## [12.7.1](https://github.com/Instabug/Instabug-React-Native/compare/v12.7.0...v12.7.1) (February 15, 2024)

android/src/main/java/com/instabug/reactlibrary/RNInstabugSessionReplayModule.java

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,13 @@
11
package com.instabug.reactlibrary;
22

3+
import androidx.annotation.Nullable;
4+
5+
import com.facebook.react.bridge.Promise;
36
import com.facebook.react.bridge.ReactApplicationContext;
47
import com.facebook.react.bridge.ReactContextBaseJavaModule;
58
import com.facebook.react.bridge.ReactMethod;
9+
import com.instabug.chat.Replies;
10+
import com.instabug.library.OnSessionReplayLinkReady;
611
import com.instabug.library.sessionreplay.SessionReplay;
712
import com.instabug.reactlibrary.utils.MainThreadHandler;
813

@@ -76,4 +81,22 @@ public void run() {
7681
}
7782
});
7883
}
84+
85+
@ReactMethod
86+
public void getSessionReplayLink(Promise promise) {
87+
MainThreadHandler.runOnMainThread(new Runnable() {
88+
@Override
89+
public void run() {
90+
SessionReplay.getSessionReplayLink(new OnSessionReplayLinkReady() {
91+
@Override
92+
public void onSessionReplayLinkReady(@Nullable String link) {
93+
94+
promise.resolve(link);
95+
}
96+
});
97+
}
98+
});
99+
100+
101+
}
79102
}

android/src/test/java/com/instabug/reactlibrary/RNInstabugSessionReplayModuleTest.java

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,27 @@
11
package com.instabug.reactlibrary;
22

33
import static org.mockito.Matchers.any;
4+
import static org.mockito.Mockito.doAnswer;
5+
import static org.mockito.Mockito.mock;
46
import static org.mockito.Mockito.mockStatic;
7+
import static org.mockito.Mockito.timeout;
58
import static org.mockito.Mockito.times;
69
import static org.mockito.Mockito.verify;
10+
import static org.mockito.Mockito.when;
711

12+
import android.os.Handler;
813
import android.os.Looper;
914

1015
import com.facebook.react.bridge.Arguments;
1116
import com.facebook.react.bridge.JavaOnlyArray;
17+
import com.facebook.react.bridge.Promise;
1218
import com.facebook.react.bridge.ReadableArray;
1319
import com.facebook.react.bridge.WritableArray;
20+
import com.instabug.chat.Replies;
1421
import com.instabug.featuresrequest.ActionType;
1522
import com.instabug.featuresrequest.FeatureRequests;
1623
import com.instabug.library.Feature;
24+
import com.instabug.library.OnSessionReplayLinkReady;
1725
import com.instabug.library.sessionreplay.SessionReplay;
1826
import com.instabug.reactlibrary.utils.MainThreadHandler;
1927

@@ -96,6 +104,29 @@ public void testSetInstabugLogsEnabled() {
96104
mockSessionReplay.verifyNoMoreInteractions();
97105
}
98106

107+
@Test
108+
public void testGetSessionReplayLink() {
109+
Promise promise = mock(Promise.class);
110+
String link="instabug link";
111+
112+
mockSessionReplay.when(() -> SessionReplay.getSessionReplayLink(any())).thenAnswer(
113+
invocation -> {
114+
OnSessionReplayLinkReady callback = (OnSessionReplayLinkReady) invocation.getArguments()[0];
115+
callback.onSessionReplayLinkReady(link);
116+
return callback;
117+
});
118+
sessionReplayModule.getSessionReplayLink(promise);
119+
120+
121+
mockSessionReplay.verify(() -> SessionReplay.getSessionReplayLink(any()));
122+
mockSessionReplay.verifyNoMoreInteractions();
123+
124+
125+
verify(promise).resolve(link);
126+
127+
128+
}
129+
99130
@Test
100131
public void testSetUserStepsEnabled() {
101132

examples/default/ios/InstabugTests/InstabugSessionReplayTests.m

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,5 +52,22 @@ - (void)testSetUserStepsEnabled {
5252
OCMVerify([self.mSessionReplay setUserStepsEnabled:enabled]);
5353
}
5454

55+
- (void)testGetSessionReplayLink {
56+
NSString *link = @"link";
57+
XCTestExpectation *expectation = [self expectationWithDescription:@"Call completion handler"];
58+
59+
RCTPromiseResolveBlock resolve = ^(NSString *result) {
60+
[expectation fulfill];
61+
XCTAssertEqualObjects(result, link);
62+
};
63+
64+
RCTPromiseRejectBlock reject = ^(NSString *code, NSString *message, NSError *error) {
65+
};
66+
OCMStub([self.mSessionReplay sessionReplayLink]).andReturn(link);
67+
[self.bridge getSessionReplayLink:resolve :reject];
68+
OCMVerify([self.mSessionReplay sessionReplayLink]);
69+
[self waitForExpectations:@[expectation] timeout:5.0];
70+
71+
}
5572

5673
@end

examples/default/src/navigation/HomeStack.tsx

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { FlatListScreen } from '../screens/user-steps/FlatListScreen';
1515
import { ComplexViewsScreen } from '../screens/user-steps/ComplexViewsScreen';
1616
import { SectionListScreen } from '../screens/user-steps/SectionListScreen';
1717
import { GesturesScreen } from '../screens/user-steps/GesturesScreen';
18+
import { SessionReplayScreen } from '../screens/SessionReplayScreen';
1819

1920
export type HomeStackParamList = {
2021
Home: undefined;
@@ -30,6 +31,7 @@ export type HomeStackParamList = {
3031
ComplexViews: undefined;
3132
SectionList: undefined;
3233
Gestures: undefined;
34+
SessionReplay: undefined;
3335
};
3436

3537
const HomeStack = createNativeStackNavigator<HomeStackParamList>();
@@ -55,6 +57,12 @@ export const HomeStackNavigator: React.FC = () => {
5557
/>
5658
<HomeStack.Screen name="Replies" component={RepliesScreen} />
5759
<HomeStack.Screen name="Surveys" component={SurveysScreen} />
60+
<HomeStack.Screen
61+
name="SessionReplay"
62+
component={SessionReplayScreen}
63+
options={{ title: 'Session Replay' }}
64+
/>
65+
5866
<HomeStack.Screen
5967
name="UserSteps"
6068
component={UserStepsScreen}

examples/default/src/screens/HomeScreen.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ export const HomeScreen: React.FC<NativeStackScreenProps<HomeStackParamList, 'Ho
1717
<ListTile title="Replies" onPress={() => navigation.navigate('Replies')} />
1818
<ListTile title="Surveys" onPress={() => navigation.navigate('Surveys')} />
1919
<ListTile title="User Steps" onPress={() => navigation.navigate('UserSteps')} />
20+
<ListTile title="Session Replay" onPress={() => navigation.navigate('SessionReplay')} />
2021
</Screen>
2122
);
2223
};
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import React from 'react';
2+
3+
import { SessionReplay } from 'instabug-reactnative';
4+
import { useToast } from 'native-base';
5+
6+
import { ListTile } from '../components/ListTile';
7+
import { Screen } from '../components/Screen';
8+
9+
export const SessionReplayScreen: React.FC = () => {
10+
const toast = useToast();
11+
return (
12+
<Screen>
13+
<ListTile
14+
title="Show Current Session link"
15+
onPress={async () => {
16+
const link = await SessionReplay.getSessionReplayLink();
17+
if (link === null) {
18+
toast.show({
19+
description: 'link not found',
20+
});
21+
} else {
22+
toast.show({
23+
description: link,
24+
});
25+
}
26+
}}
27+
/>
28+
</Screen>
29+
);
30+
};

ios/RNInstabug/InstabugSessionReplayBridge.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
- (void)setUserStepsEnabled:(BOOL)isEnabled;
2020

21+
- (void)getSessionReplayLink:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject;
2122

2223
@end
2324

ios/RNInstabug/InstabugSessionReplayBridge.m

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,12 @@ + (BOOL)requiresMainQueueSetup
3939
IBGSessionReplay.userStepsEnabled = isEnabled;
4040
}
4141

42+
RCT_EXPORT_METHOD(getSessionReplayLink:
43+
(RCTPromiseResolveBlock) resolve :(RCTPromiseRejectBlock)reject) {
44+
NSString *link = IBGSessionReplay.sessionReplayLink;
45+
resolve(link);
46+
}
47+
4248
@synthesize description;
4349

4450
@synthesize hash;

src/modules/SessionReplay.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,3 +63,15 @@ export const setInstabugLogsEnabled = (isEnabled: boolean) => {
6363
export const setUserStepsEnabled = (isEnabled: boolean) => {
6464
NativeSessionReplay.setUserStepsEnabled(isEnabled);
6565
};
66+
67+
/**
68+
* Retrieves current session's replay link.
69+
*
70+
* @example
71+
* ```ts
72+
* SessionReplay.getSessionReplayLink();
73+
* ```
74+
*/
75+
export const getSessionReplayLink = async (): Promise<string> => {
76+
return NativeSessionReplay.getSessionReplayLink();
77+
};

src/native/NativeSessionReplay.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ export interface SessionReplayNativeModule extends NativeModule {
77
setNetworkLogsEnabled(isEnabled: boolean): void;
88
setInstabugLogsEnabled(isEnabled: boolean): void;
99
setUserStepsEnabled(isEnabled: boolean): void;
10+
getSessionReplayLink(): Promise<string>;
1011
}
1112

1213
export const NativeSessionReplay = NativeModules.IBGSessionReplay;

test/mocks/mockSessionReplay.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const mockSessionReplay: SessionReplayNativeModule = {
77
setNetworkLogsEnabled: jest.fn(),
88
setInstabugLogsEnabled: jest.fn(),
99
setUserStepsEnabled: jest.fn(),
10+
getSessionReplayLink: jest.fn().mockReturnValue('link'),
1011
};
1112

1213
export default mockSessionReplay;

test/modules/SessionReplay.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,4 +29,11 @@ describe('Session Replay Module', () => {
2929
expect(NativeSessionReplay.setUserStepsEnabled).toBeCalledTimes(1);
3030
expect(NativeSessionReplay.setUserStepsEnabled).toBeCalledWith(true);
3131
});
32+
33+
it('should call the native method getSessionReplayLink', () => {
34+
SessionReplay.getSessionReplayLink();
35+
36+
expect(NativeSessionReplay.getSessionReplayLink).toBeCalledTimes(1);
37+
expect(NativeSessionReplay.getSessionReplayLink).toReturnWith('link');
38+
});
3239
});

0 commit comments

Comments
 (0)