Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[NoQA] e2e: record messageSent interaction #43302

Merged
merged 8 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/CONST.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
50 changes: 40 additions & 10 deletions src/libs/E2E/tests/reportTypingTest.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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');

Expand All @@ -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;
}
Expand All @@ -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();
Expand Down
Original file line number Diff line number Diff line change
@@ -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';
Expand Down Expand Up @@ -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';
Expand Down Expand Up @@ -102,6 +104,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 @@ -295,12 +300,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;
Expand Down Expand Up @@ -525,5 +534,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/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';
Expand All @@ -11,6 +11,7 @@ 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 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 {isSmallScreenWidth} = useWindowDimensions();

useEffect(() => {
Performance.markEnd(CONST.TIMING.MESSAGE_SENT, {message: text});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm just curious if we need to measure it after each text change or if it should be used only once

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, basically this effect will be called every time (i. e. for each text message), but since there is no corresponding start event -> such measurements will be ignored. And we'll get measurements only for associated end/start events with the same text/message. I hope I answered on the question 😅

}, [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
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 @@ -144,8 +144,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
Loading