From b45399dcb5537a6dc87228a06fd053749b947ef0 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Fri, 7 Jun 2024 17:04:25 +0200 Subject: [PATCH 1/6] e2e: record message_sent interaction --- src/CONST.ts | 1 + src/libs/E2E/tests/reportTypingTest.e2e.ts | 50 +++++++++++++++---- .../ReportActionCompose.tsx | 10 +++- .../report/comment/TextCommentFragment.tsx | 7 ++- tests/e2e/nativeCommands/adbBackspace.ts | 5 +- tests/e2e/nativeCommands/adbTypeText.ts | 3 +- tests/e2e/nativeCommands/index.ts | 2 +- tests/e2e/server/index.ts | 4 +- 8 files changed, 62 insertions(+), 20 deletions(-) diff --git a/src/CONST.ts b/src/CONST.ts index aa3ade14b040..8a941cd63bc6 100755 --- a/src/CONST.ts +++ b/src/CONST.ts @@ -917,6 +917,7 @@ const CONST = { SWITCH_REPORT: 'switch_report', 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 817bda941611..525e39f833dd 100644 --- a/src/libs/E2E/tests/reportTypingTest.e2e.ts +++ b/src/libs/E2E/tests/reportTypingTest.e2e.ts @@ -5,14 +5,18 @@ 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'; const test = (config: NativeConfig) => { + const message = `Measure_performance#${Math.floor(Math.random() * 1000000)}`; + // check for login (if already logged in the action will simply resolve) console.debug('[E2E] Logging in for typing'); @@ -28,7 +32,25 @@ 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', + duration: entry.duration, + }).then(messageSentResolve); + return; + } + if (entry.name !== CONST.TIMING.SIDEBAR_LOADED) { return; } @@ -46,17 +68,25 @@ 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', - renderCount: rerenderCount, - }).then(E2EClient.submitTestDone); - }, 3000); - }) + E2EClient.submitTestResults({ + branch: Config.E2E_BRANCH, + name: 'Composer typing rerender count', + renderCount: rerenderCount, + }) + .then(renderTimesResolve) + .then(resolve); + }, 3000); + }), + ) + .then(() => E2EClient.sendNativeCommand(NativeCommands.makeBackspaceCommand())) + .then(() => E2EClient.sendNativeCommand(NativeCommands.makeTypeTextCommand(message))) + .then(() => 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 adf358ab416d..ac8040484b6e 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -37,10 +37,12 @@ import * as EmojiPickerActions from '@userActions/EmojiPickerAction'; import * as Report from '@userActions/Report'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; +import Performance from '@libs/Performance'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; +import noop from 'lodash/noop'; import AttachmentPickerWithMenuItems from './AttachmentPickerWithMenuItems'; import ComposerWithSuggestions from './ComposerWithSuggestions'; import type {ComposerWithSuggestionsProps} from './ComposerWithSuggestions/ComposerWithSuggestions'; @@ -102,6 +104,8 @@ const shouldFocusInputOnScreenFocus = canFocusInputOnScreenFocus(); const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc(); +let onSubmitAction = noop; + function ReportActionCompose({ blockedFromConcierge, currentUserPersonalDetails = {}, @@ -295,12 +299,16 @@ function ReportActionCompose({ return; } + Performance.markStart(CONST.TIMING.MESSAGE_SENT, {message: newComment}); + playSound(SOUNDS.DONE); onSubmit(newComment); }, [onSubmit], ); + onSubmitAction = submitForm; + const onTriggerAttachmentPicker = useCallback(() => { isNextModalWillOpenRef.current = true; isKeyboardVisibleWhenShowingModalRef.current = true; @@ -525,5 +533,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 cf1ab6f8aa19..bdfdd5f0c479 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/lib/str'; 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'; @@ -13,6 +13,7 @@ import * as DeviceCapabilities from '@libs/DeviceCapabilities'; import * as EmojiUtils from '@libs/EmojiUtils'; import variables from '@styles/variables'; import CONST from '@src/CONST'; +import Performance from '@libs/Performance'; import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage'; import type {Message} from '@src/types/onyx/ReportAction'; import RenderCommentHTML from './RenderCommentHTML'; @@ -48,6 +49,10 @@ function TextCommentFragment({fragment, styleAsDeleted, styleAsMuted = false, so const {translate} = useLocalize(); const {isSmallScreenWidth} = useWindowDimensions(); + 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/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 52e50fefc0ae..e14cda0e0cba 100644 --- a/tests/e2e/server/index.ts +++ b/tests/e2e/server/index.ts @@ -144,8 +144,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; From f3ae4d645b92cd1d918866984c726c880f960521 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Mon, 10 Jun 2024 10:57:51 +0200 Subject: [PATCH 2/6] fix: eslint --- .../home/report/ReportActionCompose/ReportActionCompose.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index ac8040484b6e..e46b1889b23c 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -104,6 +104,7 @@ const shouldFocusInputOnScreenFocus = canFocusInputOnScreenFocus(); const willBlurTextInputOnTapOutside = willBlurTextInputOnTapOutsideFunc(); +// eslint-disable-next-line import/no-mutable-exports let onSubmitAction = noop; function ReportActionCompose({ From 06f87b37c8eae6c6baa089d28edbca50a45b9e89 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Mon, 10 Jun 2024 11:26:46 +0200 Subject: [PATCH 3/6] fix: prettier --- .../home/report/ReportActionCompose/ReportActionCompose.tsx | 4 ++-- src/pages/home/report/comment/TextCommentFragment.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index e46b1889b23c..f3599f9358c5 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -1,4 +1,5 @@ import {PortalHost} from '@gorhom/portal'; +import noop from 'lodash/noop'; import type {SyntheticEvent} from 'react'; import React, {memo, useCallback, useEffect, useMemo, useRef, useState} from 'react'; import type {MeasureInWindowOnSuccessCallback, NativeSyntheticEvent, TextInputFocusEventData, TextInputSelectionChangeEventData} from 'react-native'; @@ -27,6 +28,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'; @@ -37,12 +39,10 @@ import * as EmojiPickerActions from '@userActions/EmojiPickerAction'; import * as Report from '@userActions/Report'; import * as User from '@userActions/User'; import CONST from '@src/CONST'; -import Performance from '@libs/Performance'; import ONYXKEYS from '@src/ONYXKEYS'; import type * as OnyxTypes from '@src/types/onyx'; import type * as OnyxCommon from '@src/types/onyx/OnyxCommon'; import {isEmptyObject} from '@src/types/utils/EmptyObject'; -import noop from 'lodash/noop'; import AttachmentPickerWithMenuItems from './AttachmentPickerWithMenuItems'; import ComposerWithSuggestions from './ComposerWithSuggestions'; import type {ComposerWithSuggestionsProps} from './ComposerWithSuggestions/ComposerWithSuggestions'; diff --git a/src/pages/home/report/comment/TextCommentFragment.tsx b/src/pages/home/report/comment/TextCommentFragment.tsx index bdfdd5f0c479..5ec68b783431 100644 --- a/src/pages/home/report/comment/TextCommentFragment.tsx +++ b/src/pages/home/report/comment/TextCommentFragment.tsx @@ -11,9 +11,9 @@ import useWindowDimensions from '@hooks/useWindowDimensions'; 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 Performance from '@libs/Performance'; import type {OriginalMessageSource} from '@src/types/onyx/OriginalMessage'; import type {Message} from '@src/types/onyx/ReportAction'; import RenderCommentHTML from './RenderCommentHTML'; From 0ebe2cdb4c62b854f44fbacc00f432f28e9baf1f Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Mon, 19 Aug 2024 15:14:31 +0200 Subject: [PATCH 4/6] fix: eslint --- .../home/report/ReportActionCompose/ReportActionCompose.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx index f7f52f51563d..07d5338d2a59 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -1,7 +1,5 @@ -import {PortalHost} from '@gorhom/portal'; -import noop from 'lodash/noop'; -import type {SyntheticEvent} from 'react'; 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'; @@ -323,6 +321,7 @@ function ReportActionCompose({ [onSubmit, reportID], ); + // eslint-disable-next-line react-compiler/react-compiler onSubmitAction = submitForm; const onTriggerAttachmentPicker = useCallback(() => { From 8143c8d9d512e382fad4e4cad6334f6c1b8ca553 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Mon, 19 Aug 2024 16:44:53 +0200 Subject: [PATCH 5/6] fix: actually make tests runnable --- src/libs/E2E/tests/reportTypingTest.e2e.ts | 4 +++- .../home/report/ReportActionCompose/ReportActionCompose.tsx | 6 +++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/libs/E2E/tests/reportTypingTest.e2e.ts b/src/libs/E2E/tests/reportTypingTest.e2e.ts index 4d3876780415..a6162092ff58 100644 --- a/src/libs/E2E/tests/reportTypingTest.e2e.ts +++ b/src/libs/E2E/tests/reportTypingTest.e2e.ts @@ -1,5 +1,6 @@ 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'; @@ -47,6 +48,7 @@ const test = (config: NativeConfig) => { branch: Config.E2E_BRANCH, name: 'Message sent', metric: entry.duration, + unit: 'ms', }).then(messageSentResolve); return; } @@ -87,7 +89,7 @@ const test = (config: NativeConfig) => { ) .then(() => E2EClient.sendNativeCommand(NativeCommands.makeBackspaceCommand())) .then(() => E2EClient.sendNativeCommand(NativeCommands.makeTypeTextCommand(message))) - .then(() => onSubmitAction()) + .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 07d5338d2a59..da7b4f72bfb6 100644 --- a/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx +++ b/src/pages/home/report/ReportActionCompose/ReportActionCompose.tsx @@ -321,9 +321,6 @@ function ReportActionCompose({ [onSubmit, reportID], ); - // eslint-disable-next-line react-compiler/react-compiler - onSubmitAction = submitForm; - const onTriggerAttachmentPicker = useCallback(() => { isNextModalWillOpenRef.current = true; isKeyboardVisibleWhenShowingModalRef.current = true; @@ -399,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; From 88c4b221ce6f4d49aab762981b09804027331f96 Mon Sep 17 00:00:00 2001 From: kirillzyusko Date: Tue, 20 Aug 2024 12:29:47 +0200 Subject: [PATCH 6/6] fix: send real message only during warmup stage --- src/libs/E2E/tests/reportTypingTest.e2e.ts | 3 +-- tests/e2e/config.ts | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libs/E2E/tests/reportTypingTest.e2e.ts b/src/libs/E2E/tests/reportTypingTest.e2e.ts index a6162092ff58..efe1c380dfd0 100644 --- a/src/libs/E2E/tests/reportTypingTest.e2e.ts +++ b/src/libs/E2E/tests/reportTypingTest.e2e.ts @@ -16,12 +16,11 @@ import ROUTES from '@src/ROUTES'; import * as NativeCommands from '../../../../tests/e2e/nativeCommands/NativeCommandsAction'; const test = (config: NativeConfig) => { - const message = `Measure_performance#${Math.floor(Math.random() * 1000000)}`; - // check for login (if already logged in the action will simply resolve) console.debug('[E2E] Logging in for typing'); const reportID = getConfigValueOrThrow('reportID', config); + const message = getConfigValueOrThrow('message', config); E2ELogin().then((neededLogin) => { if (neededLogin) { 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,