diff --git a/src/CONST.ts b/src/CONST.ts
index a9160e606bd9..b52a37889e00 100755
--- a/src/CONST.ts
+++ b/src/CONST.ts
@@ -976,6 +976,7 @@ const CONST = {
SWITCH_REPORT_THREAD: 'switch_report_thread',
SIDEBAR_LOADED: 'sidebar_loaded',
LOAD_SEARCH_OPTIONS: 'load_search_options',
+ MESSAGE_SENT: 'message_sent',
COLD: 'cold',
WARM: 'warm',
REPORT_ACTION_ITEM_LAYOUT_DEBOUNCE_TIME: 1500,
diff --git a/src/libs/E2E/tests/reportTypingTest.e2e.ts b/src/libs/E2E/tests/reportTypingTest.e2e.ts
index 9624d7ab992b..efe1c380dfd0 100644
--- a/src/libs/E2E/tests/reportTypingTest.e2e.ts
+++ b/src/libs/E2E/tests/reportTypingTest.e2e.ts
@@ -1,13 +1,16 @@
import type {NativeConfig} from 'react-native-config';
import Config from 'react-native-config';
+import {runOnUI} from 'react-native-reanimated';
import E2ELogin from '@libs/E2E/actions/e2eLogin';
import waitForAppLoaded from '@libs/E2E/actions/waitForAppLoaded';
import waitForKeyboard from '@libs/E2E/actions/waitForKeyboard';
import E2EClient from '@libs/E2E/client';
import getConfigValueOrThrow from '@libs/E2E/utils/getConfigValueOrThrow';
+import getPromiseWithResolve from '@libs/E2E/utils/getPromiseWithResolve';
import Navigation from '@libs/Navigation/Navigation';
import Performance from '@libs/Performance';
import {getRerenderCount, resetRerenderCount} from '@pages/home/report/ReportActionCompose/ComposerWithSuggestions/index.e2e';
+import {onSubmitAction} from '@pages/home/report/ReportActionCompose/ReportActionCompose';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';
import * as NativeCommands from '../../../../tests/e2e/nativeCommands/NativeCommandsAction';
@@ -17,6 +20,7 @@ const test = (config: NativeConfig) => {
console.debug('[E2E] Logging in for typing');
const reportID = getConfigValueOrThrow('reportID', config);
+ const message = getConfigValueOrThrow('message', config);
E2ELogin().then((neededLogin) => {
if (neededLogin) {
@@ -28,7 +32,26 @@ const test = (config: NativeConfig) => {
console.debug('[E2E] Logged in, getting typing metrics and submitting themโฆ');
+ const [renderTimesPromise, renderTimesResolve] = getPromiseWithResolve();
+ const [messageSentPromise, messageSentResolve] = getPromiseWithResolve();
+
+ Promise.all([renderTimesPromise, messageSentPromise]).then(() => {
+ console.debug(`[E2E] Submitting!`);
+
+ E2EClient.submitTestDone();
+ });
+
Performance.subscribeToMeasurements((entry) => {
+ if (entry.name === CONST.TIMING.MESSAGE_SENT) {
+ E2EClient.submitTestResults({
+ branch: Config.E2E_BRANCH,
+ name: 'Message sent',
+ metric: entry.duration,
+ unit: 'ms',
+ }).then(messageSentResolve);
+ return;
+ }
+
if (entry.name !== CONST.TIMING.SIDEBAR_LOADED) {
return;
}
@@ -46,18 +69,26 @@ const test = (config: NativeConfig) => {
return Promise.resolve();
})
.then(() => E2EClient.sendNativeCommand(NativeCommands.makeTypeTextCommand('A')))
- .then(() => {
- setTimeout(() => {
- const rerenderCount = getRerenderCount();
+ .then(
+ () =>
+ new Promise((resolve) => {
+ setTimeout(() => {
+ const rerenderCount = getRerenderCount();
- E2EClient.submitTestResults({
- branch: Config.E2E_BRANCH,
- name: 'Composer typing rerender count',
- metric: rerenderCount,
- unit: 'renders',
- }).then(E2EClient.submitTestDone);
- }, 3000);
- })
+ E2EClient.submitTestResults({
+ branch: Config.E2E_BRANCH,
+ name: 'Composer typing rerender count',
+ metric: rerenderCount,
+ unit: 'renders',
+ })
+ .then(renderTimesResolve)
+ .then(resolve);
+ }, 3000);
+ }),
+ )
+ .then(() => E2EClient.sendNativeCommand(NativeCommands.makeBackspaceCommand()))
+ .then(() => E2EClient.sendNativeCommand(NativeCommands.makeTypeTextCommand(message)))
+ .then(() => runOnUI(onSubmitAction)())
.catch((error) => {
console.error('[E2E] Error while test', error);
E2EClient.submitTestDone();
diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
index 005824fa949f..da7b4f72bfb6 100644
--- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
+++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx
@@ -1,4 +1,5 @@
import {useNavigation} from '@react-navigation/native';
+import noop from 'lodash/noop';
import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react';
import type {MeasureInWindowOnSuccessCallback, NativeSyntheticEvent, TextInputFocusEventData, TextInputSelectionChangeEventData} from 'react-native';
import {View} from 'react-native';
@@ -31,6 +32,7 @@ import canFocusInputOnScreenFocus from '@libs/canFocusInputOnScreenFocus';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import {getDraftComment} from '@libs/DraftCommentUtils';
import getModalState from '@libs/getModalState';
+import Performance from '@libs/Performance';
import * as ReportUtils from '@libs/ReportUtils';
import playSound, {SOUNDS} from '@libs/Sound';
import willBlurTextInputOnTapOutsideFunc from '@libs/willBlurTextInputOnTapOutside';
@@ -116,6 +118,9 @@ const shouldFocusInputOnScreenFocus = canFocusInputOnScreenFocus();
const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc();
+// eslint-disable-next-line import/no-mutable-exports
+let onSubmitAction = noop;
+
function ReportActionCompose({
blockedFromConcierge,
currentUserPersonalDetails,
@@ -309,6 +314,7 @@ function ReportActionCompose({
Report.addAttachment(reportID, attachmentFileRef.current, newCommentTrimmed);
attachmentFileRef.current = null;
} else {
+ Performance.markStart(CONST.TIMING.MESSAGE_SENT, {message: newCommentTrimmed});
onSubmit(newCommentTrimmed);
}
},
@@ -390,6 +396,9 @@ function ReportActionCompose({
clearComposer();
}, [isSendDisabled, isReportReadyForDisplay, composerRefShared]);
+ // eslint-disable-next-line react-compiler/react-compiler
+ onSubmitAction = handleSendMessage;
+
const emojiShiftVertical = useMemo(() => {
const chatItemComposeSecondaryRowHeight = styles.chatItemComposeSecondaryRow.height + styles.chatItemComposeSecondaryRow.marginTop + styles.chatItemComposeSecondaryRow.marginBottom;
const reportActionComposeHeight = styles.chatItemComposeBox.minHeight + chatItemComposeSecondaryRowHeight;
@@ -594,5 +603,5 @@ export default withCurrentUserPersonalDetails(
},
})(memo(ReportActionCompose)),
);
-
+export {onSubmitAction};
export type {SuggestionsRef, ComposerRef};
diff --git a/src/pages/home/report/comment/TextCommentFragment.tsx b/src/pages/home/report/comment/TextCommentFragment.tsx
index 68827de96172..9d1a4d9ad4b7 100644
--- a/src/pages/home/report/comment/TextCommentFragment.tsx
+++ b/src/pages/home/report/comment/TextCommentFragment.tsx
@@ -1,6 +1,6 @@
import {Str} from 'expensify-common';
import {isEmpty} from 'lodash';
-import React, {memo} from 'react';
+import React, {memo, useEffect} from 'react';
import type {StyleProp, TextStyle} from 'react-native';
import Text from '@components/Text';
import ZeroWidthView from '@components/ZeroWidthView';
@@ -11,6 +11,7 @@ import useThemeStyles from '@hooks/useThemeStyles';
import convertToLTR from '@libs/convertToLTR';
import * as DeviceCapabilities from '@libs/DeviceCapabilities';
import * as EmojiUtils from '@libs/EmojiUtils';
+import Performance from '@libs/Performance';
import variables from '@styles/variables';
import CONST from '@src/CONST';
import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage';
@@ -48,6 +49,10 @@ function TextCommentFragment({fragment, styleAsDeleted, styleAsMuted = false, so
const {translate} = useLocalize();
const {shouldUseNarrowLayout} = useResponsiveLayout();
+ useEffect(() => {
+ Performance.markEnd(CONST.TIMING.MESSAGE_SENT, {message: text});
+ }, [text]);
+
// If the only difference between fragment.text and fragment.html is
tags and emoji tag
// on native, we render it as text, not as html
// on other device, only render it as text if the only difference is
tag
diff --git a/tests/e2e/config.ts b/tests/e2e/config.ts
index 8963e07c31c8..bdb24bee0bc5 100644
--- a/tests/e2e/config.ts
+++ b/tests/e2e/config.ts
@@ -83,6 +83,7 @@ export default {
},
// Crowded Policy (Do Not Delete) Report, has a input bar available:
reportID: '8268282951170052',
+ message: `Measure_performance#${Math.floor(Math.random() * 1000000)}`,
},
[TEST_NAMES.ChatOpening]: {
name: TEST_NAMES.ChatOpening,
diff --git a/tests/e2e/nativeCommands/adbBackspace.ts b/tests/e2e/nativeCommands/adbBackspace.ts
index 2891d1daf0e9..112a80bdb37e 100644
--- a/tests/e2e/nativeCommands/adbBackspace.ts
+++ b/tests/e2e/nativeCommands/adbBackspace.ts
@@ -1,10 +1,9 @@
import execAsync from '../utils/execAsync';
import * as Logger from '../utils/logger';
-const adbBackspace = () => {
+const adbBackspace = (): Promise => {
Logger.log(`๐ Pressing backspace`);
- execAsync(`adb shell input keyevent KEYCODE_DEL`);
- return true;
+ return execAsync(`adb shell input keyevent KEYCODE_DEL`).then(() => true);
};
export default adbBackspace;
diff --git a/tests/e2e/nativeCommands/adbTypeText.ts b/tests/e2e/nativeCommands/adbTypeText.ts
index 72fefbd25d26..deea16b198c8 100644
--- a/tests/e2e/nativeCommands/adbTypeText.ts
+++ b/tests/e2e/nativeCommands/adbTypeText.ts
@@ -3,8 +3,7 @@ import * as Logger from '../utils/logger';
const adbTypeText = (text: string) => {
Logger.log(`๐ Typing text: ${text}`);
- execAsync(`adb shell input text "${text}"`);
- return true;
+ return execAsync(`adb shell input text "${text}"`).then(() => true);
};
export default adbTypeText;
diff --git a/tests/e2e/nativeCommands/index.ts b/tests/e2e/nativeCommands/index.ts
index 31af618c8ec1..310aa2ab3c22 100644
--- a/tests/e2e/nativeCommands/index.ts
+++ b/tests/e2e/nativeCommands/index.ts
@@ -4,7 +4,7 @@ import adbTypeText from './adbTypeText';
// eslint-disable-next-line rulesdir/prefer-import-module-contents
import {NativeCommandsAction} from './NativeCommandsAction';
-const executeFromPayload = (actionName?: string, payload?: NativeCommandPayload): boolean => {
+const executeFromPayload = (actionName?: string, payload?: NativeCommandPayload): Promise => {
switch (actionName) {
case NativeCommandsAction.scroll:
throw new Error('Not implemented yet');
diff --git a/tests/e2e/server/index.ts b/tests/e2e/server/index.ts
index 494b8b4644e1..512492908049 100644
--- a/tests/e2e/server/index.ts
+++ b/tests/e2e/server/index.ts
@@ -169,8 +169,8 @@ const createServerInstance = (): ServerInstance => {
case Routes.testNativeCommand: {
getPostJSONRequestData(req, res)
- ?.then((data) => {
- const status = nativeCommands.executeFromPayload(data?.actionName, data?.payload);
+ ?.then((data) => nativeCommands.executeFromPayload(data?.actionName, data?.payload))
+ .then((status) => {
if (status) {
res.end('ok');
return;