Skip to content

Commit

Permalink
Merge pull request #33491 from callstack-internal/feat/33229/OptionsS…
Browse files Browse the repository at this point in the history
…elector-reassure-perf-tests

[NoQA] add perf tests to OptionsSelector
  • Loading branch information
mountiny authored Dec 27, 2023
2 parents 68b3f22 + f21e59b commit b826689
Show file tree
Hide file tree
Showing 3 changed files with 132 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/components/OptionsList/BaseOptionsList.js
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,7 @@ function BaseOptionsList({
onViewableItemsChanged={onViewableItemsChanged}
bounces={bounces}
ListFooterComponent={renderFooterContent}
testID="options-list"
/>
</>
)}
Expand Down
1 change: 1 addition & 0 deletions src/components/OptionsSelector/BaseOptionsSelector.js
Original file line number Diff line number Diff line change
Expand Up @@ -492,6 +492,7 @@ class BaseOptionsSelector extends Component {
spellCheck={false}
shouldInterceptSwipe={this.props.shouldTextInputInterceptSwipe}
isLoading={this.props.isLoadingNewOptions}
testID="options-selector-input"
/>
);
const optionsList = (
Expand Down
130 changes: 130 additions & 0 deletions tests/perf-test/OptionsSelector.perf-test.js
Original file line number Diff line number Diff line change
@@ -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 (
<Component
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
translate={() => ''}
/>
);
}
WrappedComponent.displayName = `WrappedComponent`;
return WrappedComponent;
});

jest.mock('../../src/components/withNavigationFocus', () => (Component) => {
function WithNavigationFocus(props) {
return (
<Component
// eslint-disable-next-line react/jsx-props-no-spreading
{...props}
isFocused={false}
/>
);
}

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 (
<OptionsSelector
value="test"
sections={sections}
// eslint-disable-next-line react/jsx-props-no-spreading
{...args}
/>
);
}

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(<OptionsSelectorWrapper />, {scenario, runs});
});

test('[OptionsSelector] should render 1 section', () => {
measurePerformance(<OptionsSelectorWrapper />, {runs});
});

test('[OptionsSelector] should render mutliple sections', () => {
const sections = generateSections(mutlipleSectionsConfig);
measurePerformance(<OptionsSelectorWrapper sections={sections} />, {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(<OptionsSelectorWrapper />, {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(<OptionsSelectorWrapper sections={sections} />, {scenario, runs});
});

0 comments on commit b826689

Please sign in to comment.