Skip to content

Commit

Permalink
Merge pull request #29083 from adhorodyski/feat/27641/reassure-lhn
Browse files Browse the repository at this point in the history
feat(27641): Performance tests of LHN with Reassure
  • Loading branch information
mountiny authored Oct 10, 2023
2 parents f550882 + 82aa875 commit 1998fa3
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 161 deletions.
1 change: 1 addition & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ module.exports = {
],
transform: {
'^.+\\.jsx?$': 'babel-jest',
'^.+\\.svg?$': 'jest-transformer-svg',
},
transformIgnorePatterns: ['<rootDir>/node_modules/(?!react-native)/'],
testPathIgnorePatterns: ['<rootDir>/node_modules'],
Expand Down
18 changes: 18 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@
"react-collapse": "^5.1.0",
"react-content-loader": "^6.1.0",
"react-dom": "18.1.0",
"react-map-gl": "^7.1.3",
"react-error-boundary": "^4.0.11",
"react-map-gl": "^7.1.3",
"react-native": "0.72.4",
"react-native-android-location-enabler": "^1.2.2",
"react-native-blob-util": "^0.17.3",
Expand Down Expand Up @@ -252,6 +252,7 @@
"jest-circus": "29.4.1",
"jest-cli": "29.4.1",
"jest-environment-jsdom": "^29.4.1",
"jest-transformer-svg": "^2.0.1",
"metro-react-native-babel-preset": "0.76.8",
"mock-fs": "^4.13.0",
"onchange": "^7.1.0",
Expand Down
1 change: 1 addition & 0 deletions src/components/LHNOptionsList/LHNOptionsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ function LHNOptionsList({style, contentContainerStyles, data, onSelectRow, optio
contentContainerStyle={contentContainerStyles}
showsVerticalScrollIndicator={false}
data={data}
testID="lhn-options-list"
keyExtractor={(item) => item}
stickySectionHeadersEnabled={false}
renderItem={renderItem}
Expand Down
1 change: 1 addition & 0 deletions src/components/LHNOptionsList/OptionRowLHN.js
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ function OptionRowLHN(props) {
// Prevent composer blur on left click
e.preventDefault();
}}
testID={optionItem.reportID}
onSecondaryInteraction={(e) => showPopover(e)}
withoutFocusOnSecondaryInteraction
activeOpacity={0.8}
Expand Down
2 changes: 1 addition & 1 deletion src/pages/home/sidebar/SidebarLinksData.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ const defaultProps = {
isLoadingReportData: true,
priorityMode: CONST.PRIORITY_MODE.DEFAULT,
betas: [],
policies: [],
policies: {},
};

function SidebarLinksData({isFocused, allReportActions, betas, chatReports, currentReportID, insets, isLoadingReportData, onLinkClick, policies, priorityMode}) {
Expand Down
103 changes: 84 additions & 19 deletions tests/perf-test/SidebarLinks.perf-test.js
Original file line number Diff line number Diff line change
@@ -1,57 +1,122 @@
import {measurePerformance} from 'reassure';
import Onyx from 'react-native-onyx';
import {fireEvent, screen} from '@testing-library/react-native';
import _ from 'underscore';
import * as LHNTestUtils from '../utils/LHNTestUtils';
import CONST from '../../src/CONST';
import ONYXKEYS from '../../src/ONYXKEYS';
import waitForBatchedUpdates from '../utils/waitForBatchedUpdates';
import wrapOnyxWithWaitForBatchedUpdates from '../utils/wrapOnyxWithWaitForBatchedUpdates';
import variables from '../../src/styles/variables';

jest.setTimeout(10000);

jest.mock('../../src/libs/Permissions');
jest.mock('../../src/libs/Navigation/Navigation');
jest.mock('../../src/components/Icon/Expensicons');

const ONYXKEYS = {
PERSONAL_DETAILS: 'personalDetails',
NVP_PRIORITY_MODE: 'nvp_priorityMode',
SESSION: 'session',
BETAS: 'betas',
COLLECTION: {
REPORT: 'report_',
REPORT_ACTIONS: 'reportActions_',
},
NETWORK: 'network',
};
jest.mock('@react-navigation/native');

beforeAll(() =>
Onyx.init({
keys: ONYXKEYS,
safeEvictionKeys: [ONYXKEYS.COLLECTION.REPORT_ACTIONS],
registerStorageEventListener: () => {},
}),
);

// Initialize the network key for OfflineWithFeedback
beforeEach(() => Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false}));
beforeEach(() => {
wrapOnyxWithWaitForBatchedUpdates(Onyx);
return Onyx.merge(ONYXKEYS.NETWORK, {isOffline: false});
});

// Clear out Onyx after each test so that each test starts with a clean slate
afterEach(() => {
Onyx.clear();
});

test('simple Sidebar render with hundred of reports', () => {
const mockReports = Array.from({length: 100}, (__, i) => {
const getMockedReportsMap = (length = 100) => {
const mockReports = Array.from({length}, (__, i) => {
const reportID = i + 1;
const emails = [`email${reportID}@test.com`];
const participants = [1, 2];
const reportKey = `${ONYXKEYS.COLLECTION.REPORT}${reportID}`;
const report = LHNTestUtils.getFakeReport(emails, 1, false);
const report = LHNTestUtils.getFakeReport(participants, 1, true);

return {[reportKey]: report};
});
const mockOnyxReports = _.assign({}, ...mockReports);

return _.assign({}, ...mockReports);
};

const mockedResponseMap = getMockedReportsMap(500);

test('should render Sidebar with 500 reports stored', () => {
const scenario = async () => {
// Query for the sidebar
await screen.findByTestId('lhn-options-list');
/**
* Query for display names of participants [1, 2].
* This will ensure that the sidebar renders a list of items.
*/
await screen.findAllByText('One, Two');
};

return waitForBatchedUpdates()
.then(() =>
Onyx.multiSet({
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
[ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS, CONST.BETAS.POLICY_ROOMS],
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD,
[ONYXKEYS.IS_LOADING_REPORT_DATA]: false,
...mockedResponseMap,
}),
)
.then(() => measurePerformance(<LHNTestUtils.MockedSidebarLinks />, {scenario}));
});

test('should scroll and click some of the items', () => {
const scenario = async () => {
const eventData = {
nativeEvent: {
contentOffset: {
y: variables.optionRowHeight * 5,
},
contentSize: {
// Dimensions of the scrollable content
height: variables.optionRowHeight * 10,
width: 100,
},
layoutMeasurement: {
// Dimensions of the device
height: variables.optionRowHeight * 5,
width: 100,
},
},
};

const lhnOptionsList = await screen.findByTestId('lhn-options-list');
expect(lhnOptionsList).toBeDefined();

fireEvent.scroll(lhnOptionsList, eventData);

const button1 = await screen.findByTestId('1');
const button2 = await screen.findByTestId('2');
fireEvent.press(button1);
fireEvent.press(button2);
};

return waitForBatchedUpdates()
.then(() =>
Onyx.multiSet({
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.DEFAULT,
[ONYXKEYS.PERSONAL_DETAILS_LIST]: LHNTestUtils.fakePersonalDetails,
...mockOnyxReports,
[ONYXKEYS.BETAS]: [CONST.BETAS.DEFAULT_ROOMS, CONST.BETAS.POLICY_ROOMS],
[ONYXKEYS.NVP_PRIORITY_MODE]: CONST.PRIORITY_MODE.GSD,
[ONYXKEYS.IS_LOADING_REPORT_DATA]: false,
...mockedResponseMap,
}),
)
.then(() => measurePerformance(<LHNTestUtils.MockedSidebarLinks />));
.then(() => measurePerformance(<LHNTestUtils.MockedSidebarLinks />, {scenario}));
});
Loading

0 comments on commit 1998fa3

Please sign in to comment.