Skip to content

Commit

Permalink
Merge pull request #43302 from margelo/e2e/message-sent-interaction
Browse files Browse the repository at this point in the history
  • Loading branch information
mountiny committed Aug 23, 2024
2 parents 844c6bf + 88c4b22 commit 156f0a2
Show file tree
Hide file tree
Showing 9 changed files with 66 additions and 21 deletions.
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -980,6 +980,7 @@ const CONST = {
OPEN_REPORT_THREAD: 'open_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,
Expand Down
53 changes: 42 additions & 11 deletions src/libs/E2E/tests/reportTypingTest.e2e.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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) {
Expand All @@ -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;
}
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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);
}
},
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -594,5 +603,5 @@ export default withCurrentUserPersonalDetails(
},
})(memo(ReportActionCompose)),
);

export {onSubmitAction};
export type {SuggestionsRef, ComposerRef};
7 changes: 6 additions & 1 deletion src/pages/home/report/comment/TextCommentFragment.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -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';
Expand Down Expand Up @@ -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 <br /> 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 <br /> tag
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 2 additions & 3 deletions tests/e2e/nativeCommands/adbBackspace.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import execAsync from '../utils/execAsync';
import * as Logger from '../utils/logger';

const adbBackspace = () => {
const adbBackspace = (): Promise<boolean> => {
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;
3 changes: 1 addition & 2 deletions tests/e2e/nativeCommands/adbTypeText.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
2 changes: 1 addition & 1 deletion tests/e2e/nativeCommands/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<boolean> => {
switch (actionName) {
case NativeCommandsAction.scroll:
throw new Error('Not implemented yet');
Expand Down
4 changes: 2 additions & 2 deletions tests/e2e/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,8 +169,8 @@ const createServerInstance = (): ServerInstance => {

case Routes.testNativeCommand: {
getPostJSONRequestData<NativeCommand>(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;
Expand Down

0 comments on commit 156f0a2

Please sign in to comment.