Skip to content

Commit e352bee

Browse files
a7medevHeshamMegid
authored andcommitted
feat: add new repro steps api (#1024)
* chore(android): add repro modes to args registry * chore(android): implement native setReproStepsConfig * test(android): test native setReproStepsConfig * chore(ios): implement native setReproStepsConfig * test(ios): test native setReproStepsConfig * feat: add setReproStepsConfig API to Instabug * test: add a proper mock for native constants * test: add tests for setReproStepsConfig * chore(ios): map crash mode enabled to no screenshot * chore: add docs for set repro steps config * chore(android): make native repro steps api non-nullable * chore: update changelog * chore: update readme * fix(android): run setReproConfigurations on UI thread
1 parent 922d25e commit e352bee

File tree

13 files changed

+201
-5
lines changed

13 files changed

+201
-5
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
- Add a new string (`StringKey.reproStepsListItemNumberingTitle`) for overriding the repro steps list item (screen) title for consistency between iOS and Android ([#1002](https://github.com/Instabug/Instabug-React-Native/pull/1002)).
1010
- Add support for RN version 0.73 by updating the `build.gradle` file with the `namespace` ([#1004](https://github.com/Instabug/Instabug-React-Native/pull/1004))
1111
- Add native-side init API which can be used to catch and report startup crashes on android. ([#1012](https://github.com/Instabug/Instabug-React-Native/pull/1012))
12+
- Add the new repro steps configuration API `Instabug.setReproStepsConfig` ([#1024](https://github.com/Instabug/Instabug-React-Native/pull/1024)).
1213

1314
### Changed
1415

@@ -19,6 +20,7 @@
1920

2021
- Deprecate the old `StringKey.discardAlertCancel` and `StringKey.discardAlertAction` string keys for overriding the discard alert buttons as they had incosistent behavior between iOS and Android ([#1001](https://github.com/Instabug/Instabug-React-Native/pull/1001)).
2122
- Deprecate the old `StringKey.reproStepsListItemNumberingTitle` string key for overriding the repro steps list item (screen) title as it had incosistent behavior between iOS and Android ([#1002](https://github.com/Instabug/Instabug-React-Native/pull/1002)).
23+
- Deprecate `Instabug.setReproStepsMode` in favor of the new `Instabug.setReproStepsConfig` ([#1024](https://github.com/Instabug/Instabug-React-Native/pull/1024)).
2224

2325
## [11.13.0](https://github.com/Instabug/Instabug-React-Native/compare/v11.12.0...v11.13.0) (July 10, 2023)
2426

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ Instabug.reportScreenChange('screenName');
125125
You can disable Repro Steps using the following API:
126126

127127
```javascript
128-
Instabug.setReproStepsMode(Instabug.reproStepsMode.disabled);
128+
Instabug.setReproStepsConfig({ all: ReproStepsMode.disabled });
129129
```
130130

131131
## Documentation

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import com.instabug.library.InstabugColorTheme;
1212
import com.instabug.library.InstabugCustomTextPlaceHolder.Key;
1313
import com.instabug.library.OnSdkDismissCallback.DismissType;
14+
import com.instabug.library.ReproMode;
1415
import com.instabug.library.core.plugin.PluginPromptOption;
1516
import com.instabug.library.extendedbugreport.ExtendedBugReport;
1617
import com.instabug.library.internal.module.InstabugLocale;
@@ -43,6 +44,7 @@ public ArrayList<T> getAll(ArrayList<String> keys) {
4344
}
4445
}
4546

47+
@SuppressWarnings("deprecation")
4648
static Map<String, Object> getAll() {
4749
return new HashMap<String, Object>() {{
4850
putAll(logLevels);
@@ -57,6 +59,7 @@ static Map<String, Object> getAll() {
5759
putAll(actionTypes);
5860
putAll(extendedBugReportStates);
5961
putAll(reproStates);
62+
putAll(reproModes);
6063
putAll(sdkLogLevels);
6164
putAll(promptOptions);
6265
putAll(locales);
@@ -140,12 +143,19 @@ static Map<String, Object> getAll() {
140143
put("disabled", ExtendedBugReport.State.DISABLED);
141144
}};
142145

146+
@Deprecated()
143147
static final ArgsMap<State> reproStates = new ArgsMap<State>() {{
144148
put("reproStepsEnabledWithNoScreenshots", State.ENABLED_WITH_NO_SCREENSHOTS);
145149
put("reproStepsEnabled", State.ENABLED);
146150
put("reproStepsDisabled", State.DISABLED);
147151
}};
148152

153+
static final ArgsMap<Integer> reproModes = new ArgsMap<Integer>() {{
154+
put("reproStepsEnabledWithNoScreenshots", ReproMode.EnableWithNoScreenshots);
155+
put("reproStepsEnabled", ReproMode.EnableWithScreenshots);
156+
put("reproStepsDisabled", ReproMode.Disable);
157+
}};
158+
149159
static final ArgsMap<Integer> sdkLogLevels = new ArgsMap<Integer>() {{
150160
put("sdkDebugLogsLevelNone", com.instabug.library.LogLevel.NONE);
151161
put("sdkDebugLogsLevelError", com.instabug.library.LogLevel.ERROR);

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

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,9 @@
2424
import com.instabug.library.Instabug;
2525
import com.instabug.library.InstabugColorTheme;
2626
import com.instabug.library.InstabugCustomTextPlaceHolder;
27+
import com.instabug.library.IssueType;
2728
import com.instabug.library.LogLevel;
29+
import com.instabug.library.ReproConfigurations;
2830
import com.instabug.library.internal.module.InstabugLocale;
2931
import com.instabug.library.invocation.InstabugInvocationEvent;
3032
import com.instabug.library.logging.InstabugLog;
@@ -49,6 +51,8 @@
4951
import java.util.Locale;
5052
import java.util.Map;
5153

54+
import javax.annotation.Nullable;
55+
5256

5357
/**
5458
* The type Rn instabug reactnative module.
@@ -761,12 +765,14 @@ public void run() {
761765
});
762766
}
763767

764-
/**
768+
/**
765769
* Sets whether user steps tracking is visual, non visual or disabled.
766770
*
767771
* @param reproStepsMode A string to set user steps tracking to be
768772
* enabled, non visual or disabled.
769773
*/
774+
@SuppressWarnings("deprecation")
775+
@Deprecated()
770776
@ReactMethod
771777
public void setReproStepsMode(final String reproStepsMode) {
772778
MainThreadHandler.runOnMainThread(new Runnable() {
@@ -782,6 +788,28 @@ public void run() {
782788
});
783789
}
784790

791+
@ReactMethod
792+
public void setReproStepsConfig(final String bugMode, final String crashMode) {
793+
MainThreadHandler.runOnMainThread(new Runnable() {
794+
@Override
795+
public void run() {
796+
try {
797+
final Integer resolvedBugMode = ArgsRegistry.reproModes.get(bugMode);
798+
final Integer resolvedCrashMode = ArgsRegistry.reproModes.get(crashMode);
799+
800+
final ReproConfigurations config = new ReproConfigurations.Builder()
801+
.setIssueMode(IssueType.Bug, resolvedBugMode)
802+
.setIssueMode(IssueType.Crash, resolvedCrashMode)
803+
.build();
804+
805+
Instabug.setReproConfigurations(config);
806+
} catch (Exception e) {
807+
e.printStackTrace();
808+
}
809+
}
810+
});
811+
}
812+
785813
/**
786814
* Shows the welcome message in a specific mode.
787815
*

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

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,9 @@
1717
import com.instabug.library.Instabug;
1818
import com.instabug.library.InstabugColorTheme;
1919
import com.instabug.library.InstabugCustomTextPlaceHolder;
20+
import com.instabug.library.IssueType;
21+
import com.instabug.library.ReproConfigurations;
22+
import com.instabug.library.ReproMode;
2023
import com.instabug.library.internal.module.InstabugLocale;
2124
import com.instabug.library.ui.onboarding.WelcomeMessage;
2225
import com.instabug.library.visualusersteps.State;
@@ -27,6 +30,7 @@
2730
import org.junit.Before;
2831
import org.junit.Test;
2932
import org.mockito.Matchers;
33+
import org.mockito.MockedConstruction;
3034
import org.mockito.MockedStatic;
3135
import org.mockito.Mockito;
3236
import org.mockito.internal.verification.VerificationModeFactory;
@@ -45,8 +49,10 @@
4549
import java.util.concurrent.Executors;
4650
import java.util.concurrent.ScheduledExecutorService;
4751

52+
import static org.mockito.ArgumentMatchers.anyInt;
4853
import static org.mockito.Matchers.any;
4954
import static org.mockito.Mockito.mock;
55+
import static org.mockito.Mockito.mockConstruction;
5056
import static org.mockito.Mockito.mockStatic;
5157
import static org.mockito.Mockito.times;
5258
import static org.mockito.Mockito.verify;
@@ -283,6 +289,28 @@ public void tearDown() {
283289
}
284290
}
285291

292+
@Test
293+
public void givenArg$setReproStepsConfig_whenQuery_thenShouldCallNativeApiWithArg() {
294+
String bug = "reproStepsEnabled";
295+
String crash = "reproStepsDisabled";
296+
297+
ReproConfigurations config = mock(ReproConfigurations.class);
298+
MockedConstruction<ReproConfigurations.Builder> mReproConfigurationsBuilder = mockConstruction(ReproConfigurations.Builder.class, (mock, context) -> {
299+
when(mock.setIssueMode(anyInt(), anyInt())).thenReturn(mock);
300+
when(mock.build()).thenReturn(config);
301+
});
302+
303+
rnModule.setReproStepsConfig(bug, crash);
304+
305+
ReproConfigurations.Builder builder = mReproConfigurationsBuilder.constructed().get(0);
306+
307+
verify(builder).setIssueMode(IssueType.Bug, ReproMode.EnableWithScreenshots);
308+
verify(builder).setIssueMode(IssueType.Crash, ReproMode.Disable);
309+
verify(builder).build();
310+
311+
mockInstabug.verify(() -> Instabug.setReproConfigurations(config));
312+
}
313+
286314
@Test
287315
public void givenArg$showWelcomeMessageWithMode_whenQuery_thenShouldCallNativeApiWithArg() {
288316
// given

examples/default/ios/InstabugTests/InstabugSampleTests.m

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,17 @@ - (void)testSetReproStepsMode {
219219
OCMVerify([mock setReproStepsMode:reproStepsMode]);
220220
}
221221

222+
- (void)testSetReproStepsConfig {
223+
id mock = OCMClassMock([Instabug class]);
224+
IBGUserStepsMode bugMode = IBGUserStepsModeDisable;
225+
IBGUserStepsMode crashMode = IBGUserStepsModeEnable;
226+
227+
[self.instabugBridge setReproStepsConfig:bugMode :crashMode];
228+
229+
OCMVerify([mock setReproStepsFor:IBGIssueTypeBug withMode:bugMode]);
230+
OCMVerify([mock setReproStepsFor:IBGIssueTypeCrash withMode:crashMode]);
231+
}
232+
222233
- (void)testSetSdkDebugLogsLevel {
223234
id mock = OCMClassMock([Instabug class]);
224235
IBGSDKDebugLogsLevel sdkDebugLogsLevel = IBGSDKDebugLogsLevelVerbose;

ios/RNInstabug/InstabugReactBridge.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161

6262
- (void)setReproStepsMode:(IBGUserStepsMode)reproStepsMode;
6363

64+
- (void)setReproStepsConfig:(IBGUserStepsMode)bugMode:(IBGUserStepsMode)crashMode;
65+
6466
- (void)setUserAttribute:(NSString *)key withValue:(NSString *)value;
6567

6668
- (void)getUserAttribute:(NSString *)key

ios/RNInstabug/InstabugReactBridge.m

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ - (dispatch_queue_t)methodQueue {
8181
[Instabug setReproStepsMode:reproStepsMode];
8282
}
8383

84+
RCT_EXPORT_METHOD(setReproStepsConfig:(IBGUserStepsMode)bugMode :(IBGUserStepsMode)crashMode) {
85+
[Instabug setReproStepsFor:IBGIssueTypeBug withMode:bugMode];
86+
[Instabug setReproStepsFor:IBGIssueTypeCrash withMode:crashMode];
87+
}
88+
8489
RCT_EXPORT_METHOD(setFileAttachment:(NSString *)fileLocation) {
8590
NSURL *url = [NSURL URLWithString:fileLocation];
8691
[Instabug addFileAttachmentWithURL:url];

src/models/ReproConfig.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import type { ReproStepsMode } from '../utils/Enums';
2+
3+
export interface ReproConfig {
4+
/**
5+
* Repro steps mode for bug reporting.
6+
*
7+
* @default ReproStepsMode.enabled
8+
*/
9+
bug?: ReproStepsMode;
10+
11+
/**
12+
* Repro steps mode for crash reporting.
13+
*
14+
* @default ReproStepsMode.enabledWithNoScreenshots
15+
*/
16+
crash?: ReproStepsMode;
17+
18+
/**
19+
* Repro steps mode for both bug and crash reporting.
20+
*
21+
* When this is set, `bug` and `crash` will be ignored.
22+
*/
23+
all?: ReproStepsMode;
24+
}

src/modules/Instabug.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ import InstabugUtils, {
3737
} from '../utils/InstabugUtils';
3838
import * as NetworkLogger from './NetworkLogger';
3939
import { captureUnhandledRejections } from '../utils/UnhandledRejectionTracking';
40+
import type { ReproConfig } from '../models/ReproConfig';
4041

4142
let _currentScreen: string | null = null;
4243
let _lastScreen: string | null = null;
@@ -365,6 +366,8 @@ export const clearLogs = () => {
365366
};
366367

367368
/**
369+
* @deprecated Use {@link setReproStepsConfig} instead.
370+
*
368371
* Sets whether user steps tracking is visual, non visual or disabled.
369372
* User Steps tracking is enabled by default if it's available
370373
* in your current plan.
@@ -375,6 +378,40 @@ export const setReproStepsMode = (mode: reproStepsMode | ReproStepsMode) => {
375378
NativeInstabug.setReproStepsMode(mode);
376379
};
377380

381+
/**
382+
* Sets the repro steps mode for bugs and crashes.
383+
*
384+
* @param config The repro steps config.
385+
*
386+
* @example
387+
* ```js
388+
* Instabug.setReproStepsConfig({
389+
* bug: ReproStepsMode.enabled,
390+
* crash: ReproStepsMode.disabled,
391+
* });
392+
* ```
393+
*/
394+
export const setReproStepsConfig = (config: ReproConfig) => {
395+
let bug = config.bug ?? ReproStepsMode.enabled;
396+
let crash = config.crash ?? ReproStepsMode.enabledWithNoScreenshots;
397+
398+
if (config.all != null) {
399+
bug = config.all;
400+
crash = config.all;
401+
}
402+
403+
// There's an issue with crashes repro steps with screenshots in the iOS SDK
404+
// at the moment, so we'll map enabled with screenshots to enabled with no
405+
// screenshots to avoid storing the images on disk if it's not needed until
406+
// this issue is fixed in a future version.
407+
if (Platform.OS === 'ios' && crash === ReproStepsMode.enabled) {
408+
/* istanbul ignore next */
409+
crash = ReproStepsMode.enabledWithNoScreenshots;
410+
}
411+
412+
NativeInstabug.setReproStepsConfig(bug, crash);
413+
};
414+
378415
/**
379416
* Sets user attribute to overwrite it's value or create a new one if it doesn't exist.
380417
*

src/native/NativeInstabug.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,9 @@ export interface InstabugNativeModule extends NativeModule {
5050
setNetworkLoggingEnabled(isEnabled: boolean): void;
5151

5252
// Repro Steps APIs //
53+
/** @deprecated */
5354
setReproStepsMode(mode: ReproStepsMode | reproStepsMode): void;
55+
setReproStepsConfig(bugMode: ReproStepsMode, crashMode: ReproStepsMode): void;
5456
setTrackUserSteps(isEnabled: boolean): void;
5557
reportScreenChange(firstScreen: string): void;
5658
addPrivateView(nativeTag: number | null): void;

test/mocks/mockInstabug.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,16 @@
11
import type { InstabugNativeModule } from '../../src/native/NativeInstabug';
22

3+
/**
4+
* A fake implementation of the NativeConstants object using `Proxy` that
5+
* returns the name of the property as its value instead of hardcoding all
6+
* the constants.
7+
*/
8+
const fakeNativeConstants = new Proxy({}, { get: (_, prop) => prop });
9+
310
const mockInstabug: InstabugNativeModule = {
11+
getConstants: jest.fn().mockReturnValue(fakeNativeConstants),
412
addListener: jest.fn(),
513
removeListeners: jest.fn(),
6-
getConstants: jest.fn().mockReturnValue({
7-
reproStepsListItemNumberingTitle: 'reproStepsListItemNumberingTitle',
8-
}),
914
setEnabled: jest.fn(),
1015
init: jest.fn(),
1116
setUserData: jest.fn(),
@@ -29,6 +34,7 @@ const mockInstabug: InstabugNativeModule = {
2934
logDebug: jest.fn(),
3035
clearLogs: jest.fn(),
3136
setReproStepsMode: jest.fn(),
37+
setReproStepsConfig: jest.fn(),
3238
setSdkDebugLogsLevel: jest.fn(),
3339
setUserAttribute: jest.fn(),
3440
getUserAttribute: jest.fn(),

test/modules/Instabug.spec.ts

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -418,6 +418,47 @@ describe('Instabug Module', () => {
418418
expect(NativeInstabug.setReproStepsMode).toBeCalledWith(mode);
419419
});
420420

421+
it('setReproStepsConfig should call the native setReproStepsConfig', () => {
422+
Platform.OS = 'android';
423+
424+
const bug = ReproStepsMode.disabled;
425+
const crash = ReproStepsMode.enabled;
426+
const config = { bug, crash };
427+
428+
Instabug.setReproStepsConfig(config);
429+
430+
expect(NativeInstabug.setReproStepsConfig).toBeCalledTimes(1);
431+
expect(NativeInstabug.setReproStepsConfig).toBeCalledWith(bug, crash);
432+
});
433+
434+
it('setReproStepsConfig should prioritize `all` over `bug` and `crash`', () => {
435+
Platform.OS = 'android';
436+
437+
const bug = ReproStepsMode.disabled;
438+
const crash = ReproStepsMode.enabled;
439+
const all = ReproStepsMode.enabledWithNoScreenshots;
440+
const config = { all, bug, crash };
441+
442+
Instabug.setReproStepsConfig(config);
443+
444+
expect(NativeInstabug.setReproStepsConfig).toBeCalledTimes(1);
445+
expect(NativeInstabug.setReproStepsConfig).toBeCalledWith(all, all);
446+
});
447+
448+
it('setReproStepsConfig should use defaults for `bug` and `crash`', () => {
449+
Platform.OS = 'android';
450+
451+
const config = {};
452+
453+
Instabug.setReproStepsConfig(config);
454+
455+
expect(NativeInstabug.setReproStepsConfig).toBeCalledTimes(1);
456+
expect(NativeInstabug.setReproStepsConfig).toBeCalledWith(
457+
ReproStepsMode.enabled,
458+
ReproStepsMode.enabledWithNoScreenshots,
459+
);
460+
});
461+
421462
it('should call the native method setSdkDebugLogsLevel on iOS', () => {
422463
const debugLevel = Instabug.sdkDebugLogsLevel.sdkDebugLogsLevelVerbose;
423464

0 commit comments

Comments
 (0)