From f21e59b09a0698d9fc77d2fd4af4a43a422ab61c Mon Sep 17 00:00:00 2001 From: Github Date: Fri, 22 Dec 2023 10:20:58 +0100 Subject: [PATCH] add perf tests to OptionsSelector --- src/components/OptionsList/BaseOptionsList.js | 1 + .../OptionsSelector/BaseOptionsSelector.js | 1 + tests/perf-test/OptionsSelector.perf-test.js | 130 ++++++++++++++++++ 3 files changed, 132 insertions(+) create mode 100644 tests/perf-test/OptionsSelector.perf-test.js diff --git a/src/components/OptionsList/BaseOptionsList.js b/src/components/OptionsList/BaseOptionsList.js index d22df00bd0b3..06e02729e46b 100644 --- a/src/components/OptionsList/BaseOptionsList.js +++ b/src/components/OptionsList/BaseOptionsList.js @@ -291,6 +291,7 @@ function BaseOptionsList({ onViewableItemsChanged={onViewableItemsChanged} bounces={bounces} ListFooterComponent={renderFooterContent} + testID="options-list" /> )} diff --git a/src/components/OptionsSelector/BaseOptionsSelector.js b/src/components/OptionsSelector/BaseOptionsSelector.js index 30e069d60aab..24bb55f5065c 100755 --- a/src/components/OptionsSelector/BaseOptionsSelector.js +++ b/src/components/OptionsSelector/BaseOptionsSelector.js @@ -489,6 +489,7 @@ class BaseOptionsSelector extends Component { spellCheck={false} shouldInterceptSwipe={this.props.shouldTextInputInterceptSwipe} isLoading={this.props.isLoadingNewOptions} + testID="options-selector-input" /> ); const optionsList = ( diff --git a/tests/perf-test/OptionsSelector.perf-test.js b/tests/perf-test/OptionsSelector.perf-test.js new file mode 100644 index 000000000000..da706d7bb629 --- /dev/null +++ b/tests/perf-test/OptionsSelector.perf-test.js @@ -0,0 +1,130 @@ +import {fireEvent} from '@testing-library/react-native'; +import React from 'react'; +import {measurePerformance} from 'reassure'; +import _ from 'underscore'; +import OptionsSelector from '@src/components/OptionsSelector'; +import CONST from '@src/CONST'; +import variables from '@src/styles/variables'; + +jest.mock('../../src/components/withLocalize', () => (Component) => { + function WrappedComponent(props) { + return ( + ''} + /> + ); + } + WrappedComponent.displayName = `WrappedComponent`; + return WrappedComponent; +}); + +jest.mock('../../src/components/withNavigationFocus', () => (Component) => { + function WithNavigationFocus(props) { + return ( + + ); + } + + WithNavigationFocus.displayName = 'WithNavigationFocus'; + + return WithNavigationFocus; +}); + +const generateSections = (sectionConfigs) => + _.map(sectionConfigs, ({numItems, indexOffset, shouldShow = true}) => ({ + data: Array.from({length: numItems}, (_v, i) => ({ + text: `Item ${i + indexOffset}`, + keyForList: `item-${i + indexOffset}`, + })), + indexOffset, + shouldShow, + })); + +const singleSectionSConfig = [{numItems: 1000, indexOffset: 0}]; + +const mutlipleSectionsConfig = [ + {numItems: 1000, indexOffset: 0}, + {numItems: 100, indexOffset: 70}, +]; + +function OptionsSelectorWrapper(args) { + const sections = generateSections(singleSectionSConfig); + return ( + + ); +} + +const runs = CONST.PERFORMANCE_TESTS.RUNS; + +test('[OptionsSelector] should render text input with interactions', () => { + const scenario = (screen) => { + const textInput = screen.getByTestId('options-selector-input'); + fireEvent.changeText(textInput, 'test'); + fireEvent.changeText(textInput, 'test2'); + fireEvent.changeText(textInput, 'test3'); + }; + + measurePerformance(, {scenario, runs}); +}); + +test('[OptionsSelector] should render 1 section', () => { + measurePerformance(, {runs}); +}); + +test('[OptionsSelector] should render mutliple sections', () => { + const sections = generateSections(mutlipleSectionsConfig); + measurePerformance(, {runs}); +}); + +test('[OptionsSelector] should press a list items', () => { + const scenario = (screen) => { + fireEvent.press(screen.getByText('Item 1')); + fireEvent.press(screen.getByText('Item 5')); + fireEvent.press(screen.getByText('Item 10')); + }; + + measurePerformance(, {scenario, runs}); +}); + +test('[OptionsSelector] should scroll and press few items', () => { + const sections = generateSections(mutlipleSectionsConfig); + + const generateEventData = (numOptions, optionRowHeight) => ({ + nativeEvent: { + contentOffset: { + y: optionRowHeight * numOptions, + }, + contentSize: { + height: optionRowHeight * 10, + width: 100, + }, + layoutMeasurement: { + height: optionRowHeight * 5, + width: 100, + }, + }, + }); + + const eventData = generateEventData(100, variables.optionRowHeight); + const eventData2 = generateEventData(200, variables.optionRowHeight); + const scenario = (screen) => { + fireEvent.press(screen.getByText('Item 10')); + fireEvent.scroll(screen.getByTestId('options-list'), eventData); + fireEvent.press(screen.getByText('Item 100')); + fireEvent.scroll(screen.getByTestId('options-list'), eventData2); + fireEvent.press(screen.getByText('Item 200')); + }; + + measurePerformance(, {scenario, runs}); +});