diff --git a/src/CONST.js b/src/CONST.js
index 26acb0412305..93fc7e222945 100755
--- a/src/CONST.js
+++ b/src/CONST.js
@@ -375,6 +375,7 @@ const CONST = {
             CONFIRM: 'confirm',
             CENTERED: 'centered',
             CENTERED_UNSWIPEABLE: 'centered_unswipeable',
+            CENTERED_SMALL: 'centered_small',
             BOTTOM_DOCKED: 'bottom_docked',
             POPOVER: 'popover',
             RIGHT_DOCKED: 'right_docked',
@@ -400,6 +401,7 @@ const CONST = {
         WARM: 'warm',
         REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500,
         SHOW_LOADING_SPINNER_DEBOUNCE_TIME: 250,
+        TEST_TOOLS_MODAL_THROTTLE_TIME: 800,
         TOOLTIP_SENSE: 1000,
         TRIE_INITIALIZATION: 'trie_initialization',
         COMMENT_LENGTH_DEBOUNCE_TIME: 500,
diff --git a/src/ONYXKEYS.js b/src/ONYXKEYS.js
index 9cb0d62731d1..fd61c0f8bc5c 100755
--- a/src/ONYXKEYS.js
+++ b/src/ONYXKEYS.js
@@ -170,6 +170,9 @@ export default {
     // Is Keyboard shortcuts modal open?
     IS_SHORTCUTS_MODAL_OPEN: 'isShortcutsModalOpen',
 
+    // Is the test tools modal open?
+    IS_TEST_TOOLS_MODAL_OPEN: 'isTestToolsModalOpen',
+
     // Stores information about active wallet transfer amount, selectedAccountID, status, etc
     WALLET_TRANSFER: 'walletTransfer',
 
diff --git a/src/components/ScreenWrapper/index.js b/src/components/ScreenWrapper/index.js
index 5c83dda89619..8fbb60428e5d 100644
--- a/src/components/ScreenWrapper/index.js
+++ b/src/components/ScreenWrapper/index.js
@@ -13,10 +13,13 @@ import OfflineIndicator from '../OfflineIndicator';
 import compose from '../../libs/compose';
 import withNavigation from '../withNavigation';
 import withWindowDimensions from '../withWindowDimensions';
+import withEnvironment from '../withEnvironment';
 import ONYXKEYS from '../../ONYXKEYS';
 import {withNetwork} from '../OnyxProvider';
 import {propTypes, defaultProps} from './propTypes';
 import SafeAreaConsumer from '../SafeAreaConsumer';
+import TestToolsModal from '../TestToolsModal';
+import TestToolsGestureDetector from '../TestToolsGestureDetector';
 import withKeyboardState from '../withKeyboardState';
 
 class ScreenWrapper extends React.Component {
@@ -111,29 +114,32 @@ class ScreenWrapper extends React.Component {
                     }
 
                     return (
-                        <View
-                            style={[
-                                ...this.props.style,
-                                styles.flex1,
-                                paddingStyle,
-                            ]}
-                        >
-                            <KeyboardAvoidingView style={[styles.w100, styles.h100, {maxHeight: this.props.windowHeight}]} behavior={this.props.keyboardAvoidingViewBehavior}>
-                                <HeaderGap />
-                                {// If props.children is a function, call it to provide the insets to the children.
-                                    _.isFunction(this.props.children)
-                                        ? this.props.children({
-                                            insets,
-                                            safeAreaPaddingBottomStyle,
-                                            didScreenTransitionEnd: this.state.didScreenTransitionEnd,
-                                        })
-                                        : this.props.children
-                                }
-                                {this.props.isSmallScreenWidth && (
-                                    <OfflineIndicator />
-                                )}
-                            </KeyboardAvoidingView>
-                        </View>
+                        <TestToolsGestureDetector>
+                            <View
+                                style={[
+                                    ...this.props.style,
+                                    styles.flex1,
+                                    paddingStyle,
+                                ]}
+                            >
+                                <KeyboardAvoidingView style={[styles.w100, styles.h100, {maxHeight: this.props.windowHeight}]} behavior={this.props.keyboardAvoidingViewBehavior}>
+                                    <HeaderGap />
+                                    {(this.props.environment === CONST.ENVIRONMENT.DEV) && <TestToolsModal />}
+                                    {// If props.children is a function, call it to provide the insets to the children.
+                                        _.isFunction(this.props.children)
+                                            ? this.props.children({
+                                                insets,
+                                                safeAreaPaddingBottomStyle,
+                                                didScreenTransitionEnd: this.state.didScreenTransitionEnd,
+                                            })
+                                            : this.props.children
+                                    }
+                                    {this.props.isSmallScreenWidth && (
+                                        <OfflineIndicator />
+                                    )}
+                                </KeyboardAvoidingView>
+                            </View>
+                        </TestToolsGestureDetector>
                     );
                 }}
             </SafeAreaConsumer>
@@ -152,6 +158,10 @@ export default compose(
         modal: {
             key: ONYXKEYS.MODAL,
         },
+        isTestToolsModalOpen: {
+            key: ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN,
+        },
     }),
     withNetwork(),
+    withEnvironment,
 )(ScreenWrapper);
diff --git a/src/components/ScreenWrapper/propTypes.js b/src/components/ScreenWrapper/propTypes.js
index 4345f60fad48..5f0e913a5980 100644
--- a/src/components/ScreenWrapper/propTypes.js
+++ b/src/components/ScreenWrapper/propTypes.js
@@ -1,4 +1,5 @@
 import PropTypes from 'prop-types';
+import {environmentPropTypes} from '../withEnvironment';
 
 const propTypes = {
     /** Array of additional styles to add */
@@ -19,6 +20,9 @@ const propTypes = {
     // Called when navigated Screen's transition is finished. It does not fire when user exit the page.
     onEntryTransitionEnd: PropTypes.func,
 
+    // Is the test tools modal open?
+    isTestToolsModalOpen: PropTypes.bool,
+
     /** The behavior to pass to the KeyboardAvoidingView, requires some trial and error depending on the layout/devices used.
      *  Search 'switch(behavior)' in ./node_modules/react-native/Libraries/Components/Keyboard/KeyboardAvoidingView.js for more context */
     keyboardAvoidingViewBehavior: PropTypes.oneOf(['padding', 'height', 'position']),
@@ -31,6 +35,8 @@ const propTypes = {
 
     /** Whether to dismiss keyboard before leaving a screen */
     shouldDismissKeyboardBeforeClose: PropTypes.bool,
+
+    ...environmentPropTypes,
 };
 
 const defaultProps = {
@@ -40,6 +46,7 @@ const defaultProps = {
     includePaddingTop: true,
     onEntryTransitionEnd: () => {},
     modal: {},
+    isTestToolsModalOpen: false,
     keyboardAvoidingViewBehavior: 'padding',
 };
 
diff --git a/src/components/TestToolMenu.js b/src/components/TestToolMenu.js
index a5e61942f240..ec99689a05f6 100644
--- a/src/components/TestToolMenu.js
+++ b/src/components/TestToolMenu.js
@@ -37,7 +37,7 @@ const defaultProps = {
 
 const TestToolMenu = props => (
     <>
-        <Text style={[styles.textLabelSupporting, styles.mb2, styles.mt6]} numberOfLines={1}>
+        <Text style={[styles.textLabelSupporting, styles.mb2]} numberOfLines={1}>
             Test Preferences
         </Text>
 
diff --git a/src/components/TestToolRow.js b/src/components/TestToolRow.js
index 5364f44537b0..deefaaf3adc0 100644
--- a/src/components/TestToolRow.js
+++ b/src/components/TestToolRow.js
@@ -13,7 +13,7 @@ const propTypes = {
 };
 
 const TestToolRow = props => (
-    <View style={[styles.flexRow, styles.mb6, styles.justifyContentBetween, styles.alignItemsCenter]}>
+    <View style={[styles.flexRow, styles.mb6, styles.justifyContentBetween, styles.alignItemsCenter, styles.mnw120]}>
         <View style={styles.flex2}>
             <Text>
                 {props.title}
diff --git a/src/components/TestToolsGestureDetector.js b/src/components/TestToolsGestureDetector.js
new file mode 100644
index 000000000000..9bd97accfe87
--- /dev/null
+++ b/src/components/TestToolsGestureDetector.js
@@ -0,0 +1,45 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {GestureDetector, Gesture} from 'react-native-gesture-handler';
+import CONST from '../CONST';
+import withEnvironment, {environmentPropTypes} from './withEnvironment';
+import * as App from '../libs/actions/App';
+
+/**
+ * If we are in the dev environment wrap the children in a gesture detector that opens a test tools modal after 5 taps
+ */
+
+const propTypes = {
+    /** Children to wrap in TestToolsGestureDetector. */
+    children: PropTypes.node.isRequired,
+
+    ...environmentPropTypes,
+};
+
+const TestToolsGestureDetector = (props) => {
+    const quintupleTap = Gesture.Tap()
+        .numberOfTaps(5)
+
+        // Run the callbacks on the JS thread otherwise there's an error on iOS
+        .runOnJS(true)
+        .onEnd(App.toggleTestToolsModal);
+
+    // The gesture to open the test tools menu should only exist in the dev environment
+    if (props.environment === CONST.ENVIRONMENT.DEV) {
+        return (
+            <GestureDetector gesture={quintupleTap}>
+                {props.children}
+            </GestureDetector>
+        );
+    }
+    return (
+        <>
+            {props.children}
+        </>
+    );
+};
+
+TestToolsGestureDetector.propTypes = propTypes;
+TestToolsGestureDetector.displayName = 'TestToolsGestureDetector';
+
+export default withEnvironment(TestToolsGestureDetector);
diff --git a/src/components/TestToolsModal.js b/src/components/TestToolsModal.js
new file mode 100644
index 000000000000..92aae8e3c810
--- /dev/null
+++ b/src/components/TestToolsModal.js
@@ -0,0 +1,44 @@
+import React from 'react';
+import PropTypes from 'prop-types';
+import {withOnyx} from 'react-native-onyx';
+import {View} from 'react-native';
+import ONYXKEYS from '../ONYXKEYS';
+import Modal from './Modal';
+import CONST from '../CONST';
+import * as App from '../libs/actions/App';
+import TestToolMenu from './TestToolMenu';
+import styles from '../styles/styles';
+
+const propTypes = {
+    /** Whether the test tools modal is open */
+    isTestToolsModalOpen: PropTypes.bool,
+};
+
+const defaultProps = {
+    isTestToolsModalOpen: false,
+};
+
+const TestToolsModal = props => (
+    <Modal
+        isVisible={props.isTestToolsModalOpen}
+        type={CONST.MODAL.MODAL_TYPE.CENTERED_SMALL}
+        onClose={App.toggleTestToolsModal}
+    >
+        <View style={[styles.settingsPageBody, styles.p5]}>
+            <TestToolMenu />
+        </View>
+    </Modal>
+);
+
+TestToolsModal.propTypes = propTypes;
+TestToolsModal.defaultProps = defaultProps;
+TestToolsModal.displayName = 'TestToolsModal';
+
+export default withOnyx({
+    modal: {
+        key: ONYXKEYS.MODAL,
+    },
+    isTestToolsModalOpen: {
+        key: ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN,
+    },
+})(TestToolsModal);
diff --git a/src/libs/actions/App.js b/src/libs/actions/App.js
index b3d05bed7f6a..7f08b7a0a836 100644
--- a/src/libs/actions/App.js
+++ b/src/libs/actions/App.js
@@ -286,6 +286,22 @@ function openProfile() {
     Navigation.navigate(ROUTES.SETTINGS_PROFILE);
 }
 
+let isTestToolsModalOpen = false;
+Onyx.connect({
+    key: ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN,
+    callback: val => isTestToolsModalOpen = val || false,
+});
+
+/**
+ * Toggle the test tools modal open or closed. Throttle the toggle to fix Android Chrome where there seems to be an extra tap which closes the modal.
+ * Throttling also makes the modal stay open if you accidentally tap an extra time, which is easy to do.
+ */
+function toggleTestToolsModal() {
+    const toggle = () => Onyx.set(ONYXKEYS.IS_TEST_TOOLS_MODAL_OPEN, !isTestToolsModalOpen);
+    const throttledToggle = _.throttle(toggle, CONST.TIMING.TEST_TOOLS_MODAL_THROTTLE_TIME);
+    throttledToggle();
+}
+
 export {
     setLocale,
     setLocaleAndNavigate,
@@ -294,4 +310,5 @@ export {
     openProfile,
     openApp,
     reconnectApp,
+    toggleTestToolsModal,
 };
diff --git a/src/styles/getModalStyles/getBaseModalStyles.js b/src/styles/getModalStyles/getBaseModalStyles.js
index 36c98880f69a..0475635a35f5 100644
--- a/src/styles/getModalStyles/getBaseModalStyles.js
+++ b/src/styles/getModalStyles/getBaseModalStyles.js
@@ -124,6 +124,37 @@ export default (type, windowDimensions, popoverAnchorPosition = {}, innerContain
             shouldAddTopSafeAreaPadding = isSmallScreenWidth;
             shouldAddBottomSafeAreaPadding = false;
             break;
+        case CONST.MODAL.MODAL_TYPE.CENTERED_SMALL:
+            // A centered modal that takes up the minimum possible screen space on all devices
+            modalStyle = {
+                ...modalStyle,
+                ...{
+                    alignItems: 'center',
+                },
+            };
+            modalContainerStyle = {
+                // Shadow Styles
+                shadowColor: themeColors.shadow,
+                shadowOffset: {
+                    width: 0,
+                    height: 0,
+                },
+                shadowOpacity: 0.1,
+                shadowRadius: 5,
+
+                borderRadius: 12,
+                borderWidth: 0,
+            };
+
+            // Allow this modal to be dismissed with a swipe down or swipe right
+            swipeDirection = ['down', 'right'];
+            animationIn = 'fadeIn';
+            animationOut = 'fadeOut';
+            shouldAddTopSafeAreaMargin = false;
+            shouldAddBottomSafeAreaMargin = false;
+            shouldAddTopSafeAreaPadding = false;
+            shouldAddBottomSafeAreaPadding = false;
+            break;
         case CONST.MODAL.MODAL_TYPE.BOTTOM_DOCKED:
             modalStyle = {
                 ...modalStyle,
diff --git a/src/styles/utilities/sizing.js b/src/styles/utilities/sizing.js
index a55774756075..1051098fbe16 100644
--- a/src/styles/utilities/sizing.js
+++ b/src/styles/utilities/sizing.js
@@ -28,6 +28,10 @@ export default {
         minWidth: '25%',
     },
 
+    mnw120: {
+        minWidth: 120,
+    },
+
     w50: {
         width: '50%',
     },
