From a4b80b2dc2e700cafef3d7c2a14a48856addb728 Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Sat, 15 Aug 2026 00:13:59 +0530 Subject: [PATCH 1/5] using a seperate button component for ui-kit button --- app/containers/UIKit/Button.tsx | 50 ++ .../__snapshots__/UiKitMessage.test.tsx.snap | 626 ++++++++-------- .../__snapshots__/UiKitModal.test.tsx.snap | 702 +++++++++--------- app/containers/UIKit/index.tsx | 2 +- 4 files changed, 698 insertions(+), 682 deletions(-) create mode 100644 app/containers/UIKit/Button.tsx diff --git a/app/containers/UIKit/Button.tsx b/app/containers/UIKit/Button.tsx new file mode 100644 index 0000000000..e16a7d13d9 --- /dev/null +++ b/app/containers/UIKit/Button.tsx @@ -0,0 +1,50 @@ +import { type FC } from 'react'; +import { Pressable, StyleSheet, Text, type StyleProp, type ViewStyle } from 'react-native'; + +import { useTheme } from '../../theme'; +import sharedStyles from '../../views/Styles'; +import ActivityIndicator from '../ActivityIndicator'; + +const styles = StyleSheet.create({ + container: { + borderRadius: 4, + paddingVertical: 14, + paddingHorizontal: 16, + justifyContent: 'center' + }, + text: { + ...sharedStyles.textMedium, + ...sharedStyles.textAlignCenter + }, + pressed: { + opacity: 0.7 + } +}); + +interface IUIKitButtonProps { + title: string; + onPress: () => void; + type?: 'primary' | 'secondary'; + loading?: boolean; + style?: StyleProp; +} + +const UIKitButton: FC = ({ title, onPress, type = 'primary', loading, style }) => { + const { colors } = useTheme(); + const isPrimary = type === 'primary'; + const backgroundColor = isPrimary ? colors.buttonBackgroundPrimaryDefault : colors.buttonBackgroundSecondaryDefault; + const color = isPrimary ? colors.fontWhite : colors.fontDefault; + + return ( + [styles.container, { backgroundColor }, style, pressed && styles.pressed]}> + {loading ? : {title}} + + ); +}; + +export default UIKitButton; diff --git a/app/containers/UIKit/__snapshots__/UiKitMessage.test.tsx.snap b/app/containers/UIKit/__snapshots__/UiKitMessage.test.tsx.snap index a8678d2bfb..db9fecd194 100644 --- a/app/containers/UIKit/__snapshots__/UiKitMessage.test.tsx.snap +++ b/app/containers/UIKit/__snapshots__/UiKitMessage.test.tsx.snap @@ -3,63 +3,59 @@ exports[`Story Snapshots: ActionButton should match snapshot 1`] = ` [ - - Approve - + , - - Deny - + , - - Deny - + , - - Deny - + , - - Deny - + , - - Deny - + , - - Deny - + , - - button - + `; diff --git a/app/containers/UIKit/__snapshots__/UiKitModal.test.tsx.snap b/app/containers/UIKit/__snapshots__/UiKitModal.test.tsx.snap index 491ab67ca3..9972a5823e 100644 --- a/app/containers/UIKit/__snapshots__/UiKitModal.test.tsx.snap +++ b/app/containers/UIKit/__snapshots__/UiKitModal.test.tsx.snap @@ -1056,63 +1056,59 @@ exports[`Story Snapshots: ModalActionsWithShowMore should match snapshot 1`] = ` } />, - - Primary Action - + , - - Secondary - + , - - Danger Action - + , - - Button 4 - + , - - Button 5 - + , - - Button 6 - Hidden - + , - - Button 7 - Hidden - + , - - Button 8 - Hidden - + , - - Change - + , Date: Mon, 17 Aug 2026 18:34:15 +0530 Subject: [PATCH 2/5] Added use no memo in Actions --- app/containers/UIKit/Actions.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/containers/UIKit/Actions.tsx b/app/containers/UIKit/Actions.tsx index 40f328ce81..aef47b9610 100644 --- a/app/containers/UIKit/Actions.tsx +++ b/app/containers/UIKit/Actions.tsx @@ -14,6 +14,8 @@ const styles = StyleSheet.create({ }); export const Actions = ({ blockId, appId, elements, parser }: IActions) => { + 'use no memo'; + const [showMoreVisible, setShowMoreVisible] = useState(() => elements && elements.length > 5); const shouldShowMore = elements && elements.length > 5; From 8e9bd2edded070c0a0f51383cca49e9b52b9af0a Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Tue, 18 Aug 2026 19:30:49 +0530 Subject: [PATCH 3/5] added story and unit test --- app/containers/UIKit/Button.stories.tsx | 20 ++ app/containers/UIKit/Button.test.tsx | 59 ++++ .../UIKit/__snapshots__/Button.test.tsx.snap | 279 ++++++++++++++++++ 3 files changed, 358 insertions(+) create mode 100644 app/containers/UIKit/Button.stories.tsx create mode 100644 app/containers/UIKit/Button.test.tsx create mode 100644 app/containers/UIKit/__snapshots__/Button.test.tsx.snap diff --git a/app/containers/UIKit/Button.stories.tsx b/app/containers/UIKit/Button.stories.tsx new file mode 100644 index 0000000000..b4b51d5bb7 --- /dev/null +++ b/app/containers/UIKit/Button.stories.tsx @@ -0,0 +1,20 @@ +import UIKitButton from './Button'; + +const buttonProps = { + title: 'Press me!', + type: 'primary' as const, + onPress: () => {} +}; + +export default { + title: 'UIKit/Button', + component: UIKitButton +}; + +export const PrimaryButton = () => ; + +export const SecondaryButton = () => ; + +export const LoadingButton = () => ; + +export const CustomStyleButton = () => ; diff --git a/app/containers/UIKit/Button.test.tsx b/app/containers/UIKit/Button.test.tsx new file mode 100644 index 0000000000..fcb296234d --- /dev/null +++ b/app/containers/UIKit/Button.test.tsx @@ -0,0 +1,59 @@ +import { fireEvent, render } from '@testing-library/react-native'; + +import UIKitButton from './Button'; +import * as stories from './Button.stories'; +import { generateSnapshots } from '../../../.rnstorybook/generateSnapshots'; + +const onPressMock = jest.fn(); + +const testProps = { + title: 'Press me!', + onPress: onPressMock +}; + +describe('UIKitButtonTests', () => { + beforeEach(() => { + onPressMock.mockClear(); + }); + + test('rendered with correct title', async () => { + const { findByText } = render(); + const buttonTitle = await findByText(testProps.title); + expect(buttonTitle).toBeTruthy(); + expect(buttonTitle.props.children).toEqual(testProps.title); + }); + + test('find button using accessibilityLabel', () => { + const { getByLabelText } = render(); + const button = getByLabelText(testProps.title); + expect(button).toBeTruthy(); + }); + + test('renders secondary variant with the same title', async () => { + const { findByText } = render(); + const buttonTitle = await findByText(testProps.title); + expect(buttonTitle).toBeTruthy(); + }); + + test('title not visible while loading', () => { + const { queryByText } = render(); + const buttonTitle = queryByText(testProps.title); + expect(buttonTitle).toBeNull(); + }); + + test('onPress is not triggered while loading', () => { + const { getByLabelText } = render(); + const button = getByLabelText(testProps.title); + fireEvent.press(button); + expect(onPressMock).not.toHaveBeenCalled(); + }); + + test('should trigger onPress function on button press', () => { + const { getByLabelText } = render(); + const button = getByLabelText(testProps.title); + fireEvent.press(button); + expect(onPressMock).toHaveBeenCalled(); + }); +}); + +generateSnapshots(stories); diff --git a/app/containers/UIKit/__snapshots__/Button.test.tsx.snap b/app/containers/UIKit/__snapshots__/Button.test.tsx.snap new file mode 100644 index 0000000000..30b67aed94 --- /dev/null +++ b/app/containers/UIKit/__snapshots__/Button.test.tsx.snap @@ -0,0 +1,279 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`Story Snapshots: CustomStyleButton should match snapshot 1`] = ` + + + Press me! + + +`; + +exports[`Story Snapshots: LoadingButton should match snapshot 1`] = ` + + + +`; + +exports[`Story Snapshots: PrimaryButton should match snapshot 1`] = ` + + + Press me! + + +`; + +exports[`Story Snapshots: SecondaryButton should match snapshot 1`] = ` + + + Press me! + + +`; From 60928a75dbfedc1d931882de1cf3a82c39ec64f0 Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Tue, 18 Aug 2026 20:19:59 +0530 Subject: [PATCH 4/5] added maestro test for button --- .maestro/tests/uikit/button-kit.yaml | 42 ++++++++++++++++++++++++++++ .sniffler/test-map.json | 4 +++ 2 files changed, 46 insertions(+) create mode 100644 .maestro/tests/uikit/button-kit.yaml diff --git a/.maestro/tests/uikit/button-kit.yaml b/.maestro/tests/uikit/button-kit.yaml new file mode 100644 index 0000000000..4bdf4ae8bb --- /dev/null +++ b/.maestro/tests/uikit/button-kit.yaml @@ -0,0 +1,42 @@ +appId: ${APP_ID} +name: UIKit Button Kit +onFlowStart: + - runFlow: '../../helpers/setup.yaml' +onFlowComplete: + - evalScript: ${output.utils.deleteCreatedUsers()} +tags: + - test-15 + +--- +- evalScript: ${output.user = output.utils.createUser()} +- evalScript: ${output.room = output.utils.createRandomRoom(output.user.username, output.user.password)} + +- runFlow: + file: '../../helpers/login-with-deeplink.yaml' + env: + USERNAME: ${output.user.username} + PASSWORD: ${output.user.password} + +- runFlow: + file: '../../helpers/navigate-to-room.yaml' + env: + ROOM: ${output.room.name} + +# here send /uikit-test command +- tapOn: + id: message-composer-input +- inputText: + text: '/uikit-test' +- extendedWaitUntil: + visible: + id: autocomplete-item-uikit-test + timeout: 10000 +- tapOn: + id: autocomplete-item-uikit-test +- tapOn: + id: 'message-composer-send' +- tapOn: Tap Me +- extendedWaitUntil: + visible: + text: '.*Button tap received! This reply is private to you*.' + timeout: 10000 diff --git a/.sniffler/test-map.json b/.sniffler/test-map.json index f7575879a9..714a65fb01 100644 --- a/.sniffler/test-map.json +++ b/.sniffler/test-map.json @@ -341,5 +341,9 @@ "app/sagas/room.js", "app/sagas/createChannel.js" ] + }, + { + "test": ".maestro/tests/uikit/button-kit.yaml", + "dependsOn": ["app/containers/UIKit/**"] } ] From 0bf7633298e1eaf3008e874c3781a08251cf3bd1 Mon Sep 17 00:00:00 2001 From: Rohit <40559587+Rohit3523@users.noreply.github.com> Date: Tue, 18 Aug 2026 20:24:02 +0530 Subject: [PATCH 5/5] using test-14 instead of 15 --- .maestro/tests/uikit/button-kit.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.maestro/tests/uikit/button-kit.yaml b/.maestro/tests/uikit/button-kit.yaml index 4bdf4ae8bb..409d12f615 100644 --- a/.maestro/tests/uikit/button-kit.yaml +++ b/.maestro/tests/uikit/button-kit.yaml @@ -5,7 +5,7 @@ onFlowStart: onFlowComplete: - evalScript: ${output.utils.deleteCreatedUsers()} tags: - - test-15 + - test-14 --- - evalScript: ${output.user = output.utils.createUser()}