Giter Site home page Giter Site logo

odemolliens / react-native-netwatch Goto Github PK

View Code? Open in Web Editor NEW
17.0 7.0 6.0 48.66 MB

Network traffic logger for React Native.

License: MIT License

Kotlin 1.04% JavaScript 1.90% TypeScript 83.76% Starlark 0.22% Java 5.87% Ruby 0.50% Swift 0.73% Objective-C 5.99%
network tracking debug redux-action react-native debugger android ios redux charles-proxy

react-native-netwatch's Introduction

Build Status npm GitHub

React Native Netwatch

Network traffic logger for React Native.
Includes an interface to see http traffic from RN and native side

Features

  • Log network requests coming from React Native side
  • Log network requests coming from the native side (iOS and Android) (optional)
  • Log Redux actions (optional)
  • Shake the device to display the tool
  • View details of each request/action
  • Generate and share the list of requests/actions in Excel (XLSX) file
  • Log connectivity change
  • Show stats between success/warning/failure requests

Example app


Getting started

Dependencies

To avoid to have too much dependencies and conflict versions, before install, you must have these dependancies in your react-native project.

  • react-native-paper
  • react-native-fs
  • react-native-share
  • @react-native-community/netinfo
  • react-native-launch-arguments

Fonts

Netwatch has react-native-vector-icons as dependency. Be sure that you have these fonts installed in your project:

  • Fontisto
  • Feather
  • MaterialCommunityIcons

Please refer to this page for more details: Install fonts react-native-vector-icons

Installation

yarn add react-native-netwatch

or

npm install react-native-netwatch

iOS

Inside your project, go to ios directory and execute pod install

cd ios && pod install && ..

OR simply

npx pod-install

Usage

Using Netwatch component

If you want add Network traffic in your project, just import 'react-native-netwatch'
and add the Netwatch component in the most higher position in the tree of components.
For example, just after your store provider or your root component

Now, when you will launch your application and shake the device, it will display automatically Netwatch.

How to activate Netwatch

You have two possibilities to activate Netwatch in your project. With a button from you app or by shaking your phone. If you want activate Netwatch with a button from your app, you must disable shake and instead pass the props onPressClose and visible.

Active Netwatch by shaking your phone

import { Netwatch } from 'react-native-netwatch';

const App = () => {
  const [netwatchVisible, setNetwatchVisible] = useState(false);

  return (
    <Provider store={store}>
      <Netwatch
        enabled={true}
        interceptIOS={true}
      />
      <AppNavigator />
    </Provider>
  );
};

export default App;

Active Netwatch with a button

import { Netwatch } from 'react-native-netwatch';

const App = () => {
  const [netwatchVisible, setNetwatchVisible] = useState(false);

  return (
    <Provider store={store}>
      <Netwatch
        enabled={true}
        interceptIOS={true}
        visible={netwatchVisible}
        onPressClose={() => setNetwatchVisible(false)}
        disableShake
      />
        <TouchableHighlight
          style={styles.openButton}
          onPress={() => setNetwatchVisible(true)}
          testID="buttonDisplayNetwatch"
        >
          <Text style={styles.textStyle}>Display Netwatch</Text>
        </TouchableHighlight>
      <AppNavigator />
    </Provider>
  );
};

export default App;

Using Netwatch as Redux middleware (optional)

You can add 'react-native-netwatch' as a middleware to catch Redux actions
To do that, just import reduxLogger from 'react-native-netwatch'

import { applyMiddleware, combineReducers, compose, createStore } from 'redux';
import appActionsReducer from './reducers/appActionsReducer';
import { reduxLogger } from 'react-native-netwatch';

const createReducer = () => (state, action) =>
  combineReducers({
    app: appActionsReducer,
  })(state, action);

const store = createStore(
  createReducer(),
  compose(applyMiddleware(reduxLogger)),
);

export default store;

Example in our demo application here

Using Netwatch to intercept and display native requests

Android (optional)

To be able to intercept requests from Android side and display them into Netwatch
You have to add to your OkHttp client Netwatch interceptor

okHttpClient.addInterceptor(new NetwatchInterceptor(context));

Example in our demo application here

iOS (optional)

Nothing to do on native side for the iOS.
You have just to set interceptIOS to true and it will intercept requests which use URLProtocol on native side and display them into Netwatch

  • To intercept request sent with Alamofire
'Bridging-Header.h'

#import <NetwatchInterceptor.h>
let configuration = URLSessionConfiguration.default
configuration.protocolClasses?.insert(NetwatchInterceptor.self, at: 0)
let sessionManager = Alamofire.SessionManager(configuration: configuration)
sessionManager.request(...)

Show stats

You can have statistics and see how many requests are succeeded or failed. By default, the indicator is closed. If you want the percentage, just press the indactor to opened it. Press again to close.

If you have applied a filter, stats are updated for current filtered view. If you have filtered to see Redux Action, the indicator is not interactive and just show a purple indicator.

Add extra informations into Redux Action items (optional)

If you want, you can add extra datas in the redux items to have more visual information. Instead of just see 'redux action' as label, your own text will be displayed. To do that, you must passed to Netwatch a props called reduxConfig. This is an object where each key correspond to a redux action in your project. All values must be string.

import { Netwatch } from 'react-native-netwatch';

const reduxConfigExample = {
  DOWNLOAD_APP_TRANSLATIONS_SUCCESS: "๐Ÿ‘จ - Extra info",
}

const App = () => {
  const [netwatchVisible, setNetwatchVisible] = useState(false);

  return (
    <Provider store={store}>
      <Netwatch
        enabled={true}
        interceptIOS={true}
        reduxConfig={reduxConfigExample}
      />
      <AppNavigator />
    </Provider>
  );
};

export default App;

You will see something like that:

โš ๏ธ Using Netwatch with Reactotron

There is a known incompatibility between Netwatch and Reactotron. If you want to redirect the requests into Reactotron, you should set the props useReactotron to true (have to reload the app if you edit its value). To go back to netwatch revert the props to false and reload again.

At this moment, it is not possible to display requests into Netwatch and Reactotron at the same time. You must choose between these tools.

Props

Params Type Default Mandatory ? Description
enabled Boolean true yes Enabled/Disabled logger to intercept request and actions
visible Boolean false no Show the main screen to display intercepted requests/actions
onPressClose Function undefined no Called when Close button is pressed in the Main screen
interceptIOS Boolean false no Intercept native iOS requests
disableShake Boolean false no Set to true to disable shake feature to display Netwatch
maxRequests Number 100 no Maximum requests displayed
showStats Boolean true no Show stats indicator
reduxConfig Object {} no Extra infos for Redux Action. Accept only string as vaulues
useReactotron Boolean false no Redirect requests to Reactotron instead of Netwatch
theme String 'dark' no Possible values are 'dark' or 'light'

Mocking Responses

Netwatch also provides a way to mock responses which is useful during testing and development.

Using Netwatch UI for Mocking

Netwatch UI provides a user-friendly way to create, export, and import mocks directly from the mobile application.

Creating Mocks

To create a mock:

  1. Open the Netwatch UI by shaking the device or triggering the configured gesture.
  2. Tap on any HTTP request in the list.
  3. Tap on the "Mock Request" button.
  4. Fill in the HTTP method, URL, status code, and response body fields. (leave blank to keep the original value)
  5. Tap "Save".

Exporting Mocks

To export a mock:

  1. Open the Netwatch UI.
  2. Navigate to the "Mock List" screen by tapping top right hamburger menu.
  3. Tap export button in the navigation bar.

The mock will be copied to the clipboard in a JSON format.

Importing Mocks

To import a mock:

  1. Copy the mock JSON to your clipboard.
  2. Open the Netwatch UI.
  3. Navigate to the "Mocked List" screen by tapping top right hamburger menu.
  4. Tap on the "Import" button.

The mock from the clipboard will be parsed and added to the list of mocked requests.

Enabling and Disabling Mocks

You can easily control which mock responses are active at any time using the Netwatch UI.

Enabling a Mock

To enable a mock:

  1. Open the Netwatch UI.
  2. Navigate to the "Mock List" screen by tapping top right hamburger menu.
  3. Find the mock response you want to enable.
  4. Tap on the mock response. When the switch is on the right and highlighted, the mock is enabled.

Disabling a Mock

To disable a mock:

  1. Open the Netwatch UI.
  2. Navigate to the "Mock List" screen by tapping top right hamburger menu.
  3. Find the mock response you want to disable.
  4. Tap on the mock response. When the switch is on the left and grayed out, the mock is disabled.

Using presets for fast Mocking

Netwatch provides three ways to mock responses with presets using props:

  • via clipboard (loadMockPresetFromClipboard)
  • via input parameters (loadMockPresetFromInputParameters)
  • via the mockPresets prop.

mockPresets

mockPresets is an array of MockResponse objects defining the mock HTTP request/response behavior.

const mockResponses = [
  {
    method: 'GET',
    url: '/api/v1/users',
    status: 200,
    body: { message: 'Success' },
  },
];

<Netwatch mockPresets={mockResponses} enabled={true} />;

loadMockPresetFromClipboard

Copy your mock response data to your clipboard in the correct format and set loadMockPresetFromClipboard to true.

loadMockPresetFromInputParameters

Set loadMockPresetFromInputParameters to true and pass the mock data as the mockPresets prop.

Note: If both loadMockPresetFromClipboard and loadMockPresetFromInputParameters are true, the data from the clipboard will be used.

Advanced Mocking Examples

Simulating Request Timeouts

Simulate request timeouts with the timeout field in MockResponse.

const mockResponses = [
  {
    method: 'GET',
    url: '/api/v1/users',
    status: 200,
    body: { message: 'Success' },
    timeout: 5, // Simulates a delay of 5 seconds
  },
];

<Netwatch mockPresets={mockResponses} enabled={true} />;

HTTP Headers Mocking

Mock HTTP headers with the headers field in MockResponse.

const mockResponses = [
  {
    method: 'GET',
    url: '/api/v1/users',
    status: 200,
    body: { message: 'Success' },
    headers: {
      'Content-Type': 'application/json',
      'X-Custom-Header': 'CustomHeaderValue',
    },
  },
];

<Netwatch mockPresets={mockResponses} enabled={true} />;

Simulating HTTP Error Statuses

Simulate HTTP error statuses such as 401, 500, and 400.

const mockResponses = [
  {
    method: 'GET',
    url: '/api/v1/secure',
    status: 401,
    body: { message: 'Unauthorized' },
  },
  {
    method: 'POST',
    url: '/api/v1/users',
    status: 500,
    body: { message: 'Internal Server Error' },
  },
  {
    method: 'POST',
    url: '/api/v1/users',
    status: 400,
    body: { message: 'Bad Request' },
  },
];

<Netwatch mockPresets={mockResponses} enabled={true} />;

Launching App with Netwatch Mocks using Appium

You can integrate Netwatch with Appium to facilitate your automation testing.

iOS

Use Appium's mobile: launchApp method to start your app with specified parameters:

const mockResponses = [
  {
    method: 'GET',
    url: '/api/v1/users',
    status: 200,
    body: { message: 'Success' }
  }
];

driver.execute('mobile: launchApp', {
  sessionId: driver.sessionId,
  bundleId: driver.capabilities.bundleId,
  arguments: ['-netwatchMocks', JSON.stringify(mockResponses)],
});

Then in your React Native application, set loadMockPresetFromInputParameters to true:

<Netwatch enabled={true} loadMockPresetFromInputParameters={true} />

Android

For Android, use Appium's startActivity method:

const mockResponses = [
  {
    method: 'GET',
    url: '/api/v1/users',
    status: 200,
    body: { message: 'Success' }
  }
];

driver.startActivity(
  driver.capabilities.appPackage,
  driver.capabilities.appActivity,
  undefined,
  undefined,
  undefined,
  undefined,
  undefined,
  `--es 'netwatchMocks' '${JSON.stringify(mockResponses)}'`
);

Then in your React Native application, set loadMockPresetFromInputParameters to true:

<Netwatch enabled={true} loadMockPresetFromInputParameters={true} />

react-native-netwatch's People

Contributors

damien5701 avatar dependabot[bot] avatar dsolimando avatar guillaumehemmen avatar imranmnts avatar odemolliens avatar snyk-bot avatar soliman13 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-native-netwatch's Issues

Improvements - Nice to have

Hello everyone,

Let's discuss here about the improvements which can be useful in Netwatch, to improve user/developer experience.

  • Netwatch which cannot be displayed with shake event in dev mode [iOS]
  • Not able to use Netwatch and Reactotron together (just have to change the value of enabled to switch)
  • Netwatch's FlatList lost the position when a new item was added [Android]. Known issue on React-native side link

[draft] make this lib expo friendly

This issue is a draft and will be edited at later stage. Current issues with expo use:

  • needs react-native-share and is not compatible with expo-sharing

Can't see any network log in release mode

"dependencies": {
"@react-native-async-storage/async-storage": "^1.12.1",
"@react-native-community/datetimepicker": "3.4.3",
"@react-native-community/image-editor": "^2.3.0",
"@react-native-community/masked-view": "^0.1.10",
"@react-native-community/netinfo": "^6.0.0",
"@react-native-community/progress-bar-android": "^1.0.4",
"@react-native-community/progress-view": "^1.2.4",
"@react-native-firebase/analytics": "^11.2.0",
"@react-native-firebase/app": "^11.2.0",
"@react-native-firebase/crashlytics": "^11.2.0",
"@react-native-firebase/perf": "^11.2.0",
"@react-native-picker/picker": "^1.15.0",
"@react-navigation/bottom-tabs": "^5.11.7",
"@react-navigation/native": "^5.9.2",
"@react-navigation/stack": "^5.14.2",
"axios": "^0.21.1",
"buffer": "^6.0.3",
"date-fns": "^2.21.1",
"deepmerge": "^4.2.2",
"expo-blur": "^9.0.3",
"expo-local-authentication": "^11.0.2",
"expo-notifications": "^0.11.5",
"formik": "^2.2.6",
"geolib": "^3.3.1",
"html-entities": "2.3.2",
"i18next": "^20.2.1",
"instabug-reactnative": "^10.0.0",
"jail-monkey": "^2.3.3",
"jetifier": "^1.6.6",
"latinize": "^0.5.0",
"notificare-push-lib-react-native": "^2.5.3",
"querystring": "0.2.1",
"react": "16.13.1",
"react-i18next": "^11.8.13",
"react-native": "0.63.4",
"react-native-circular-progress": "^1.3.7",
"react-native-config": "^1.4.2",
"react-native-device-info": "^8.1.0",
"react-native-fs": "^2.17.0",
"react-native-geocoding": "^0.4.0",
"react-native-geolocation-service": "^5.2.0",
"react-native-gesture-handler": "^1.10.1",
"react-native-highlight-words": "^1.0.1",
"react-native-image-pan-zoom": "^2.1.12",
"react-native-image-picker": "^2.3.1",
"react-native-image-size": "^1.1.3",
"react-native-keyboard-aware-scroll-view": "^0.9.3",
"react-native-localize": "^2.0.2",
"react-native-logging-tools": "^1.3.0",
"react-native-maps": "0.27.1",
"react-native-modal": "^11.10.0",
"react-native-netwatch": "^1.2.4",
"react-native-paper": "^4.8.1",
"react-native-pdf": "6.3.0",
"react-native-permissions": "^3.0.0",
"react-native-picker-select": "^8.0.4",
"react-native-safe-area-context": "^3.2.0",
"react-native-screens": "^3.1.1",
"react-native-sensitive-info": "^6.0.0-alpha.9",
"react-native-share": "5.2.2",
"react-native-splash-screen": "^3.2.0",
"react-native-svg": "^12.1.1-0",
"react-native-svg-transformer": "^0.14.3",
"react-native-swiper": "^1.6.0",
"react-native-unimodules": "^0.13.3",
"react-native-user-inactivity": "^1.2.0",
"react-native-vector-icons": "^8.1.0",
"react-native-webview": "^11.4.0",
"react-navigation-backhandler": "^2.0.1",
"react-redux": "^7.2.2",
"redux": "^4.0.5",
"redux-persist": "^6.0.0",
"redux-persist-sensitive-storage": "git+https://github.com/Squirel-SI/redux-persist-sensitive-storage.git",
"redux-saga": "^1.1.3",
"reselect": "^4.0.0",
"rn-fetch-blob": "^0.12.0",
"tealium-react-native": "^2.0.2",
"yup": "0.32.9"
},

Issue (iOS & Android)

When running the app on debug mode, I can see logs of redux actions & network calls as expected, when running the app in release mode, there are only redux actions that are logged, I can't see any network call.

Debug mode logs
โœ… Redux actions
โœ… Network calls

Release mode logs
โœ… Redux actions
โŒ Network calls

Example project crash on metro

When running the example application from a freshly cloned project, the application crashes right after launch:

error: Error: Unable to resolve module @babel/runtime/helpers/interopRequireDefault from /Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/src/index.tsx: @babel/runtime/helpers/interopRequireDefault could not be found within the project or in these directories:
  ../../../../node_modules

If you are sure the module exists, try these steps:
 1. Clear watchman watches: watchman watch-del-all
 2. Delete node_modules and run yarn install
 3. Reset Metro's cache: yarn start --reset-cache
 4. Remove the cache: rm -rf /tmp/metro-*
> 1 | import * as React from 'react';
  2 | import { useState } from 'react';
  3 | import { Modal, NativeModules, DeviceEventEmitter, useColorScheme, View } from 'react-native';
  4 | import { Details } from './Components/Details';
    at ModuleResolver.resolveDependency (/Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/node-haste/DependencyGraph/ModuleResolution.js:234:15)
    at DependencyGraph.resolveDependency (/Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/node-haste/DependencyGraph.js:413:43)
    at Object.resolve (/Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/lib/transformHelpers.js:317:42)
    at resolve (/Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/DeltaBundler/traverseDependencies.js:629:33)
    at /Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/DeltaBundler/traverseDependencies.js:645:26
    at Array.reduce (<anonymous>)
    at resolveDependencies (/Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/DeltaBundler/traverseDependencies.js:644:33)
    at /Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/DeltaBundler/traverseDependencies.js:329:33
    at Generator.next (<anonymous>)
    at asyncGeneratorStep (/Users/ghemmen/SourceCodePro/ARHS/react-native-netwatch/example/node_modules/metro/src/DeltaBundler/traverseDependencies.js:137:24)
    ```

Any support/plan of Privacy Manifest?

Recently, Apple announced that, starting May 1, they would start enforcing that all new apps and updates must declare approved reasons for using specific APIs in a privacy manifest, preventing uploads to TestFlight if the requirement is not met. These requirements also apply to 3rd party SDK's, with specific SDK's identified by Apple requiring a signature in addition to the manifest.

RN >=0.71

* What went wrong:
The Android Gradle plugin supports only Kotlin Gradle plugin version 1.5.20 and higher.
The following dependencies do not satisfy the required version:
project ':react-native-netwatch' -> org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10

No Log coming for network requests

Added for network logs but on shake its coming as empty
Added for redux and it logs all the redux actions with their payload

Check this screen shot for the Netwatch added to root of page
Screenshot 2021-09-11 at 11 13 19 AM

For API call in my project, I am using Axios

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.