Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 8 additions & 19 deletions examples/default/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { ActivityIndicator, StyleSheet } from 'react-native';
import React, { useEffect } from 'react';
import { StyleSheet } from 'react-native';

import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
Expand Down Expand Up @@ -40,13 +40,11 @@ export const App: React.FC = () => {

const navigationRef = useNavigationContainerRef();

const [isInstabugInitialized, setIsInstabugInitialized] = useState(false);

const initializeInstabug = async () => {
const initializeInstabug = () => {
try {
SessionReplay.setSyncCallback((data) => shouldSyncSession(data));

await Instabug.init({
Instabug.init({
token: 'deb1910a7342814af4e4c9210c786f35',
invocationEvents: [InvocationEvent.floatingButton],
debugLogsLevel: LogLevel.verbose,
Expand All @@ -55,21 +53,16 @@ export const App: React.FC = () => {

CrashReporting.setNDKCrashesEnabled(true);
Instabug.setReproStepsConfig({ all: ReproStepsMode.enabled });

setIsInstabugInitialized(true); // Set to true after initialization
} catch (error) {
console.error('Instabug initialization failed:', error);
setIsInstabugInitialized(true); // Proceed even if initialization fails
}
};

useEffect(() => {
initializeInstabug().then(() => {
NetworkLogger.setNetworkDataObfuscationHandler(async (networkData) => {
networkData.url = `${networkData.url}/JS/Obfuscated`;
return networkData;
});
// NetworkLogger.setRequestFilterExpression('false');
initializeInstabug();
NetworkLogger.setNetworkDataObfuscationHandler(async (networkData) => {
networkData.url = `${networkData.url}/JS/Obfuscated`;
return networkData;
});
});

Expand All @@ -80,10 +73,6 @@ export const App: React.FC = () => {
return unregisterListener;
}, [navigationRef]);

if (!isInstabugInitialized) {
return <ActivityIndicator size="large" color="#0000ff" style={styles.loading} />;
}

return (
<GestureHandlerRootView style={styles.root}>
<NativeBaseProvider theme={nativeBaseTheme}>
Expand Down
2 changes: 1 addition & 1 deletion ios/RNInstabug/InstabugNetworkLoggerBridge.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ typedef NS_ENUM(NSInteger, NetworkListenerType) {
+------------------------------------------------------------------------+
*/

- (void)isNativeInterceptionEnabled:(RCTPromiseResolveBlock _Nullable )resolve :(RCTPromiseRejectBlock _Nullable )reject;
- (BOOL)isNativeInterceptionEnabled;

- (void) registerNetworkLogsListener:(NetworkListenerType)listenerType;

Expand Down
8 changes: 5 additions & 3 deletions ios/RNInstabug/InstabugNetworkLoggerBridge.m
Original file line number Diff line number Diff line change
Expand Up @@ -69,9 +69,11 @@ -(void)stopObserving {
// Remove upstream listeners, stop unnecessary background tasks
}

RCT_EXPORT_METHOD(isNativeInterceptionEnabled:(RCTPromiseResolveBlock)resolve :(RCTPromiseRejectBlock)reject) {
resolve(@(IBGNetworkLogger.isNativeNetworkInterceptionFeatureEnabled));
}
RCT_EXPORT_BLOCKING_SYNCHRONOUS_METHOD(isNativeInterceptionEnabled) {
return @(IBGNetworkLogger.isNativeNetworkInterceptionFeatureEnabled);
}



RCT_EXPORT_METHOD(registerNetworkLogsListener: (NetworkListenerType) listenerType) {
switch (listenerType) {
Expand Down
11 changes: 6 additions & 5 deletions src/modules/Instabug.ts
Original file line number Diff line number Diff line change
Expand Up @@ -84,14 +84,17 @@ function reportCurrentViewForAndroid(screenName: string | null) {
* Should be called in constructor of the AppRegistry component
* @param config SDK configurations. See {@link InstabugConfig} for more info.
*/
export const init = async (config: InstabugConfig) => {
export const init = (config: InstabugConfig) => {
if (Platform.OS === 'android') {
// Add android feature flags listener for android
registerFeatureFlagsListener();
addOnFeatureUpdatedListener(config);
} else {
isNativeInterceptionFeatureEnabled = await NativeNetworkLogger.isNativeInterceptionEnabled();
isNativeInterceptionFeatureEnabled = NativeNetworkLogger.isNativeInterceptionEnabled();

console.log(
'Andrew: isNativeInterceptionFeatureEnabled: ' + isNativeInterceptionFeatureEnabled,
);
// Add app state listener to handle background/foreground transitions
addAppStateListener(async (nextAppState) => handleAppStateChange(nextAppState, config));

Expand Down Expand Up @@ -133,7 +136,6 @@ const handleAppStateChange = async (nextAppState: AppStateStatus, config: Instab
// Checks if the app has come to the foreground
if (['inactive', 'background'].includes(_currentAppState) && nextAppState === 'active') {
const isUpdated = await fetchApmNetworkFlags();

if (isUpdated) {
refreshAPMNetworkConfigs(config);
}
Expand All @@ -147,8 +149,7 @@ const handleAppStateChange = async (nextAppState: AppStateStatus, config: Instab
*/
const fetchApmNetworkFlags = async () => {
let isUpdated = false;
const newNativeInterceptionFeatureEnabled =
await NativeNetworkLogger.isNativeInterceptionEnabled();
const newNativeInterceptionFeatureEnabled = NativeNetworkLogger.isNativeInterceptionEnabled();
if (isNativeInterceptionFeatureEnabled !== newNativeInterceptionFeatureEnabled) {
isNativeInterceptionFeatureEnabled = newNativeInterceptionFeatureEnabled;
isUpdated = true;
Expand Down
2 changes: 1 addition & 1 deletion src/native/NativeNetworkLogger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export enum NetworkListenerType {
}

export interface NetworkLoggerNativeModule extends NativeModule {
isNativeInterceptionEnabled(): Promise<boolean>;
isNativeInterceptionEnabled(): boolean;

registerNetworkLogsListener(type?: NetworkListenerType): void;

Expand Down
67 changes: 28 additions & 39 deletions test/modules/Instabug.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ describe('Instabug Module', () => {
expect(NativeInstabug.reportScreenChange).toBeCalledWith(screenName);
});

it("componentDidAppearListener shouldn't call the native method reportScreenChange if first screen", async () => {
await Instabug.init({
it("componentDidAppearListener shouldn't call the native method reportScreenChange if first screen", () => {
Instabug.init({
token: 'some-token',
invocationEvents: [InvocationEvent.none],
});
Expand All @@ -81,14 +81,19 @@ describe('Instabug Module', () => {
componentType: 'Component',
});

await waitForExpect(() => {
waitForExpect(() => {
// Only first screen should be reported
expect(NativeInstabug.reportScreenChange).toBeCalledTimes(1);
expect(NativeInstabug.reportScreenChange).toBeCalledWith('Initial Screen');
});
});

it("componentDidAppearListener shouldn't call the native method reportScreenChange twice if same screen", (done) => {
Instabug.init({
token: 'some-token',
invocationEvents: [InvocationEvent.none],
});

Array(5).forEach(() => {
Instabug.componentDidAppearListener({
componentId: '1',
Expand All @@ -107,7 +112,7 @@ describe('Instabug Module', () => {
// 2. Second+ calls:
// The screen name is the same as _lastScreen (stored in 1st call)
// so it doesn't report a screen change
expect(NativeInstabug.reportScreenChange).not.toBeCalled();
expect(NativeInstabug.reportScreenChange).toBeCalledTimes(1);
done();
}, 1500);
});
Expand Down Expand Up @@ -283,7 +288,7 @@ describe('Instabug Module', () => {
expect(onStateChangeMock).toHaveBeenCalledWith(mockNavigationContainerRef.getRootState());
});

it('should call the native method init', async () => {
it('should call the native method init', () => {
const instabugConfig = {
token: 'some-token',
invocationEvents: [InvocationEvent.floatingButton, InvocationEvent.shake],
Expand All @@ -292,7 +297,7 @@ describe('Instabug Module', () => {
};
const usesNativeNetworkInterception = false;

await Instabug.init(instabugConfig);
Instabug.init(instabugConfig);

expect(NetworkLogger.setEnabled).toBeCalledWith(true);
expect(NativeInstabug.init).toBeCalledTimes(1);
Expand All @@ -314,7 +319,7 @@ describe('Instabug Module', () => {
expect(NativeInstabug.setCodePushVersion).toBeCalledWith(codePushVersion);
});

it('init should disable JavaScript interceptor when using native interception mode', async () => {
it('init should disable JavaScript interceptor when using native interception mode', () => {
const instabugConfig = {
token: 'some-token',
invocationEvents: [InvocationEvent.floatingButton, InvocationEvent.shake],
Expand All @@ -324,12 +329,10 @@ describe('Instabug Module', () => {
};

// Stubbing Network feature flags
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(true));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(true);
jest.spyOn(NativeNetworkLogger, 'hasAPMNetworkPlugin').mockReturnValue(Promise.resolve(true));

await Instabug.init(instabugConfig);
Instabug.init(instabugConfig);

if (Platform.OS === 'android') {
expect(NetworkLogger.setEnabled).not.toBeCalled();
Expand Down Expand Up @@ -956,11 +959,9 @@ describe('Instabug iOS initialization tests', () => {
});

it('should initialize correctly with native interception mode when [isNativeInterceptionEnabled] == ture', async () => {
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(true));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(true);

await Instabug.init(config);
Instabug.init(config);

expect(NativeNetworkLogger.isNativeInterceptionEnabled).toHaveBeenCalled();
expect(NetworkLogger.setEnabled).toHaveBeenCalledWith(false);
Expand All @@ -974,11 +975,9 @@ describe('Instabug iOS initialization tests', () => {
});

it('should disable native interception mode when user sets networkInterceptionMode to native and [isNativeInterceptionEnabled] == false', async () => {
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(false));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(false);

await Instabug.init(config);
Instabug.init(config);

expect(NativeNetworkLogger.isNativeInterceptionEnabled).toHaveBeenCalled();
expect(NetworkLogger.setEnabled).toHaveBeenCalled();
Expand All @@ -992,12 +991,10 @@ describe('Instabug iOS initialization tests', () => {
});

it('should display error message when user sets networkInterceptionMode to native and [isNativeInterceptionEnabled] == false', async () => {
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(false));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(false);
const logSpy = jest.spyOn(global.console, 'error');

await Instabug.init(config);
Instabug.init(config);

expect(logSpy).toBeCalledTimes(1);
expect(logSpy).toBeCalledWith(
Expand Down Expand Up @@ -1037,13 +1034,11 @@ describe('Instabug Android initialization tests', () => {
});

it('should show warning message when networkInterceptionMode == javascript and user added APM plugin', async () => {
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(true));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(true);
jest.spyOn(NativeNetworkLogger, 'hasAPMNetworkPlugin').mockReturnValue(Promise.resolve(true));
const logSpy = jest.spyOn(global.console, 'warn');

await Instabug.init(config);
Instabug.init(config);
fakeTimer(() => {
expect(logSpy).toBeCalledTimes(1);
expect(logSpy).toBeCalledWith(
Expand All @@ -1055,13 +1050,11 @@ describe('Instabug Android initialization tests', () => {
it('should show error message when networkInterceptionMode == native and user did not add APM plugin', async () => {
config.networkInterceptionMode = NetworkInterceptionMode.native;

jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(true));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(true);
jest.spyOn(NativeNetworkLogger, 'hasAPMNetworkPlugin').mockReturnValue(Promise.resolve(false));
const logSpy = jest.spyOn(global.console, 'error');

await Instabug.init(config);
Instabug.init(config);

fakeTimer(() => {
expect(logSpy).toBeCalledTimes(1);
Expand All @@ -1074,13 +1067,11 @@ describe('Instabug Android initialization tests', () => {
it('should show error message when networkInterceptionMode == native and user did not add APM plugin and the isNativeInterceptionEnabled is disabled', async () => {
config.networkInterceptionMode = NetworkInterceptionMode.native;

jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(false));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(false);
jest.spyOn(NativeNetworkLogger, 'hasAPMNetworkPlugin').mockReturnValue(Promise.resolve(false));
const logSpy = jest.spyOn(global.console, 'error');

await Instabug.init(config);
Instabug.init(config);

fakeTimer(() => {
expect(logSpy).toBeCalledTimes(1);
Expand All @@ -1092,13 +1083,11 @@ describe('Instabug Android initialization tests', () => {

it('should show error message when networkInterceptionMode == native and the isNativeInterceptionEnabled is disabled', async () => {
config.networkInterceptionMode = NetworkInterceptionMode.native;
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(false));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(false);
jest.spyOn(NativeNetworkLogger, 'hasAPMNetworkPlugin').mockReturnValue(Promise.resolve(true));
const logSpy = jest.spyOn(global.console, 'error');

await Instabug.init(config);
Instabug.init(config);

fakeTimer(() => {
expect(logSpy).toBeCalledTimes(1);
Expand Down
6 changes: 2 additions & 4 deletions test/utils/InstabugUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,11 +273,9 @@ describe('reportNetworkLog', () => {

it('reportNetworkLog should send network logs to native with the correct parameters on Android', async () => {
Platform.OS = 'android';
jest
.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled')
.mockReturnValue(Promise.resolve(false));
jest.spyOn(NativeNetworkLogger, 'isNativeInterceptionEnabled').mockReturnValue(false);
jest.spyOn(NativeNetworkLogger, 'hasAPMNetworkPlugin').mockReturnValue(Promise.resolve(false));
await Instabug.init({ token: '', invocationEvents: [InvocationEvent.none] });
Instabug.init({ token: '', invocationEvents: [InvocationEvent.none] });

const requestHeaders = JSON.stringify(network.requestHeaders);
const responseHeaders = JSON.stringify(network.responseHeaders);
Expand Down