Skip to content

Commit

Permalink
Merge pull request #36791 from margelo/feat/23229-linking-e2e
Browse files Browse the repository at this point in the history
Comment linking e2e
  • Loading branch information
roryabraham authored Mar 25, 2024
2 parents bbc41c2 + 625a59f commit 5f9a057
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 4 deletions.
2 changes: 1 addition & 1 deletion metro.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ require('dotenv').config();
const defaultConfig = getDefaultConfig(__dirname);

const isE2ETesting = process.env.E2E_TESTING === 'true';
const e2eSourceExts = ['e2e.js', 'e2e.ts'];
const e2eSourceExts = ['e2e.js', 'e2e.ts', 'e2e.tsx'];

/**
* Metro configuration
Expand Down
2 changes: 1 addition & 1 deletion src/ROUTES.ts
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ const ROUTES = {
REPORT: 'r',
REPORT_WITH_ID: {
route: 'r/:reportID?/:reportActionID?',
getRoute: (reportID: string) => `r/${reportID}` as const,
getRoute: (reportID: string, reportActionID?: string) => (reportActionID ? (`r/${reportID}/${reportActionID}` as const) : (`r/${reportID}` as const)),
},
REPORT_AVATAR: {
route: 'r/:reportID/avatar',
Expand Down
54 changes: 54 additions & 0 deletions src/components/InvertedFlatList/BaseInvertedFlatList/index.e2e.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
import React, {forwardRef, useMemo} from 'react';
import type {FlatListProps, ScrollViewProps, ViewToken} from 'react-native';
import {FlatList} from 'react-native';
import type {ReportAction} from '@src/types/onyx';

type BaseInvertedFlatListProps = FlatListProps<ReportAction> & {
shouldEnableAutoScrollToTopThreshold?: boolean;
};

const AUTOSCROLL_TO_TOP_THRESHOLD = 128;

let localViewableItems: ViewToken[];
const getViewableItems = () => localViewableItems;

function BaseInvertedFlatListE2e(props: BaseInvertedFlatListProps, ref: React.ForwardedRef<FlatList<ReportAction>>) {
const {shouldEnableAutoScrollToTopThreshold, ...rest} = props;

const handleViewableItemsChanged = useMemo(
() =>
({viewableItems}: {viewableItems: ViewToken[]}) => {
localViewableItems = viewableItems;
},
[],
);

const maintainVisibleContentPosition = useMemo(() => {
const config: ScrollViewProps['maintainVisibleContentPosition'] = {
// This needs to be 1 to avoid using loading views as anchors.
minIndexForVisible: 1,
};

if (shouldEnableAutoScrollToTopThreshold) {
config.autoscrollToTopThreshold = AUTOSCROLL_TO_TOP_THRESHOLD;
}

return config;
}, [shouldEnableAutoScrollToTopThreshold]);

return (
<FlatList<ReportAction>
// eslint-disable-next-line react/jsx-props-no-spreading
{...rest}
ref={ref}
maintainVisibleContentPosition={maintainVisibleContentPosition}
inverted
onViewableItemsChanged={handleViewableItemsChanged}
/>
);
}

BaseInvertedFlatListE2e.displayName = 'BaseInvertedFlatListE2e';

export default forwardRef(BaseInvertedFlatListE2e);
export {getViewableItems};
1 change: 1 addition & 0 deletions src/libs/E2E/reactNativeLaunchingTest.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ const tests: Tests = {
[E2EConfig.TEST_NAMES.OpenSearchPage]: require('./tests/openSearchPageTest.e2e').default,
[E2EConfig.TEST_NAMES.ChatOpening]: require('./tests/chatOpeningTest.e2e').default,
[E2EConfig.TEST_NAMES.ReportTyping]: require('./tests/reportTypingTest.e2e').default,
[E2EConfig.TEST_NAMES.Linking]: require('./tests/linkingTest.e2e').default,
};

// Once we receive the TII measurement we know that the app is initialized and ready to be used:
Expand Down
70 changes: 70 additions & 0 deletions src/libs/E2E/tests/linkingTest.e2e.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import type {NativeConfig} from 'react-native-config';
import Config from 'react-native-config';
import {getViewableItems} from '@components/InvertedFlatList/BaseInvertedFlatList/index.e2e';
import Timing from '@libs/actions/Timing';
import E2ELogin from '@libs/E2E/actions/e2eLogin';
import waitForAppLoaded from '@libs/E2E/actions/waitForAppLoaded';
import E2EClient from '@libs/E2E/client';
import getConfigValueOrThrow from '@libs/E2E/utils/getConfigValueOrThrow';
import Navigation from '@libs/Navigation/Navigation';
import Performance from '@libs/Performance';
import CONST from '@src/CONST';
import ROUTES from '@src/ROUTES';

const test = (config: NativeConfig) => {
console.debug('[E2E] Logging in for comment linking');

const reportID = getConfigValueOrThrow('reportID', config);
const linkedReportID = getConfigValueOrThrow('linkedReportID', config);
const linkedReportActionID = getConfigValueOrThrow('linkedReportActionID', config);

E2ELogin().then((neededLogin) => {
if (neededLogin) {
return waitForAppLoaded().then(() => E2EClient.submitTestDone());
}

Performance.subscribeToMeasurements((entry) => {
if (entry.name === CONST.TIMING.SIDEBAR_LOADED) {
console.debug('[E2E] Sidebar loaded, navigating to a report…');
Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(reportID));
return;
}

if (entry.name === CONST.TIMING.REPORT_INITIAL_RENDER) {
console.debug('[E2E] Navigating to linked report action…');
Timing.start(CONST.TIMING.SWITCH_REPORT);
Performance.markStart(CONST.TIMING.SWITCH_REPORT);

Navigation.navigate(ROUTES.REPORT_WITH_ID.getRoute(linkedReportID, linkedReportActionID));
return;
}

if (entry.name === CONST.TIMING.SWITCH_REPORT) {
console.debug('[E2E] Linking: 1');
setTimeout(() => {
const res = getViewableItems();
console.debug('[E2E] Viewable items retrieved, verifying correct message…');

if (!!res && res[0]?.item?.reportActionID === linkedReportActionID) {
E2EClient.submitTestResults({
branch: Config.E2E_BRANCH,
name: 'Comment linking',
duration: entry.duration,
})
.then(() => {
console.debug('[E2E] Test completed successfully, exiting…');
E2EClient.submitTestDone();
})
.catch((err) => {
console.debug('[E2E] Error while submitting test results:', err);
});
} else {
console.debug('[E2E] Message verification failed');
}
}, 3000);
}
});
});
};

export default test;
4 changes: 2 additions & 2 deletions src/pages/home/report/ReportActionsView.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -344,15 +344,15 @@ function ReportActionsView({
}

didLayout.current = true;
Timing.end(CONST.TIMING.SWITCH_REPORT, hasCachedActionOnFirstRender ? CONST.TIMING.WARM : CONST.TIMING.COLD);

// Capture the init measurement only once not per each chat switch as the value gets overwritten
if (!ReportActionsView.initMeasured) {
Performance.markEnd(CONST.TIMING.REPORT_INITIAL_RENDER);
Timing.end(CONST.TIMING.REPORT_INITIAL_RENDER);
ReportActionsView.initMeasured = true;
} else {
Performance.markEnd(CONST.TIMING.SWITCH_REPORT);
}
Timing.end(CONST.TIMING.SWITCH_REPORT, hasCachedActionOnFirstRender ? CONST.TIMING.WARM : CONST.TIMING.COLD);
}, [hasCachedActionOnFirstRender]);

useEffect(() => {
Expand Down
11 changes: 11 additions & 0 deletions tests/e2e/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const TEST_NAMES = {
OpenSearchPage: 'Open search page TTI',
ReportTyping: 'Report typing',
ChatOpening: 'Chat opening',
Linking: 'Linking',
};

/**
Expand Down Expand Up @@ -87,6 +88,16 @@ export default {
// #announce Chat with many messages
reportID: '5421294415618529',
},
[TEST_NAMES.Linking]: {
name: TEST_NAMES.Linking,
reportScreen: {
autoFocus: true,
},
// Crowded Policy (Do Not Delete) Report, has a input bar available:
reportID: '8268282951170052',
linkedReportID: '5421294415618529',
linkedReportActionID: '2845024374735019929',
},
},
};

Expand Down

0 comments on commit 5f9a057

Please sign in to comment.