From 013110a3dd2b64de070dd1818184eaff90750f0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cl=C3=B3vis=20Neto?= Date: Tue, 17 Dec 2024 16:44:30 +0100 Subject: [PATCH] feat: Create initial onboarding screens (#58) * feat: create onboarding structure * feat: create onboarding carousel components * feat: create onboarding header component * feat: create onboarding container * feat: crate re-usable SafeButton component * feat: cover onboarding components with unit tests * feat: add storybook for carousel component * feat: fix unit tests * feat: remove hardcoded colors and test warnings * fix: remove unused testID * fix: remove magic numbers * feat: use tamagui variables --- apps/mobile/app/_layout.tsx | 7 + apps/mobile/app/index.tsx | 8 + apps/mobile/assets/images/anywhere.png | Bin 0 -> 22673 bytes apps/mobile/assets/images/illustration.png | Bin 0 -> 49728 bytes apps/mobile/assets/images/safe-wallet.png | Bin 0 -> 1721 bytes .../SafeButton/SafeButton.stories.tsx | 18 ++ .../src/components/SafeButton/SafeButton.tsx | 27 +++ .../mobile/src/components/SafeButton/index.ts | 2 + .../Onboarding/Onboarding.container.test.tsx | 26 +++ .../Onboarding/Onboarding.container.tsx | 19 ++ .../CarouselFeedback.test.tsx | 21 +++ .../OnboardingCarousel/CarouselFeedback.tsx | 35 ++++ .../OnboardingCarousel/CarouselItem.test.tsx | 33 ++++ .../OnboardingCarousel/CarouselItem.tsx | 28 +++ .../OnboardingCarousel.stories.tsx | 25 +++ .../OnboardingCarousel.test.tsx | 24 +++ .../OnboardingCarousel/OnboardingCarousel.tsx | 40 +++++ .../components/OnboardingCarousel/index.ts | 2 + .../components/OnboardingCarousel/items.tsx | 101 +++++++++++ .../OnboardingHeader.test.tsx | 10 ++ .../OnboardingHeader/OnboardingHeader.tsx | 16 ++ .../components/OnboardingHeader/index.ts | 2 + .../ParticlesLogo/ParticlesLogo.test.tsx | 10 ++ .../ParticlesLogo/ParticlesLogo.tsx | 45 +++++ .../__snapshots__/ParticlesLogo.test.tsx.snap | 169 ++++++++++++++++++ .../components/ParticlesLogo/index.ts | 2 + apps/mobile/src/features/Onboarding/index.ts | 2 + apps/mobile/src/tests/jest.setup.tsx | 6 + 28 files changed, 678 insertions(+) create mode 100644 apps/mobile/app/index.tsx create mode 100644 apps/mobile/assets/images/anywhere.png create mode 100644 apps/mobile/assets/images/illustration.png create mode 100644 apps/mobile/assets/images/safe-wallet.png create mode 100644 apps/mobile/src/components/SafeButton/SafeButton.stories.tsx create mode 100644 apps/mobile/src/components/SafeButton/SafeButton.tsx create mode 100644 apps/mobile/src/components/SafeButton/index.ts create mode 100644 apps/mobile/src/features/Onboarding/Onboarding.container.test.tsx create mode 100644 apps/mobile/src/features/Onboarding/Onboarding.container.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.test.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.test.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.stories.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.test.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/index.ts create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingCarousel/items.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.test.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/OnboardingHeader/index.ts create mode 100644 apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.test.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.tsx create mode 100644 apps/mobile/src/features/Onboarding/components/ParticlesLogo/__snapshots__/ParticlesLogo.test.tsx.snap create mode 100644 apps/mobile/src/features/Onboarding/components/ParticlesLogo/index.ts create mode 100644 apps/mobile/src/features/Onboarding/index.ts diff --git a/apps/mobile/app/_layout.tsx b/apps/mobile/app/_layout.tsx index 2865ab4c46..356e3fc515 100644 --- a/apps/mobile/app/_layout.tsx +++ b/apps/mobile/app/_layout.tsx @@ -12,6 +12,7 @@ import { BottomSheetModalProvider } from '@gorhom/bottom-sheet' import { PortalProvider } from '@tamagui/portal' import { SafeToastProvider } from '@/src/theme/provider/toastProvider' import { configureReanimatedLogger, ReanimatedLogLevel } from 'react-native-reanimated' +import { OnboardingHeader } from '@/src/features/Onboarding/components/OnboardingHeader' configureReanimatedLogger({ level: ReanimatedLogLevel.warn, @@ -43,6 +44,12 @@ function RootLayout() { ), })} > + diff --git a/apps/mobile/app/index.tsx b/apps/mobile/app/index.tsx new file mode 100644 index 0000000000..5d869fe8b2 --- /dev/null +++ b/apps/mobile/app/index.tsx @@ -0,0 +1,8 @@ +import { Onboarding } from '@/src/features/Onboarding' +import React from 'react' + +function OnboardingPage() { + return +} + +export default OnboardingPage diff --git a/apps/mobile/assets/images/anywhere.png b/apps/mobile/assets/images/anywhere.png new file mode 100644 index 0000000000000000000000000000000000000000..11fc00015b2d4ff5cbd21650c569b63e8b4798cf GIT binary patch literal 22673 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 T;)ehR;WNhi=Ks{_K7Rc_Z%RM4 literal 0 HcmV?d00001 diff --git a/apps/mobile/assets/images/illustration.png b/apps/mobile/assets/images/illustration.png new file mode 100644 index 0000000000000000000000000000000000000000..a483b9d30aaf51961edaa08cbd414245a07dd286 GIT binary patch literal 49728 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 = { + title: 'SafeButton', + component: SafeButton, + args: { + label: 'Get started', + onPress: action('onPress'), + }, +} + +export default meta + +type Story = StoryObj + +export const Default: Story = {} diff --git a/apps/mobile/src/components/SafeButton/SafeButton.tsx b/apps/mobile/src/components/SafeButton/SafeButton.tsx new file mode 100644 index 0000000000..503a36883a --- /dev/null +++ b/apps/mobile/src/components/SafeButton/SafeButton.tsx @@ -0,0 +1,27 @@ +import React from 'react' +import { TouchableOpacity } from 'react-native' +import { styled, Text, View } from 'tamagui' + +interface SafeButtonProps { + onPress: () => void + label: string +} + +export const StyledButtonWrapper = styled(View, { + height: 48, + alignItems: 'center', + justifyContent: 'center', + borderRadius: 8, +}) + +export function SafeButton({ onPress, label }: SafeButtonProps) { + return ( + + + + {label} + + + + ) +} diff --git a/apps/mobile/src/components/SafeButton/index.ts b/apps/mobile/src/components/SafeButton/index.ts new file mode 100644 index 0000000000..4e666e4309 --- /dev/null +++ b/apps/mobile/src/components/SafeButton/index.ts @@ -0,0 +1,2 @@ +import { SafeButton } from './SafeButton' +export { SafeButton } diff --git a/apps/mobile/src/features/Onboarding/Onboarding.container.test.tsx b/apps/mobile/src/features/Onboarding/Onboarding.container.test.tsx new file mode 100644 index 0000000000..0c4fe03678 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/Onboarding.container.test.tsx @@ -0,0 +1,26 @@ +import React from 'react' +import { Onboarding } from './Onboarding.container' +import { fireEvent, render } from '@/src/tests/test-utils' + +const mockNavigate = jest.fn() + +jest.mock('expo-router', () => ({ + useRouter: () => ({ + navigate: mockNavigate, + }), +})) + +describe('Onboarding Component', () => { + it('renders correctly', () => { + const { getAllByText } = render() + expect(getAllByText('Get started')).toHaveLength(1) + }) + + it('navigates on button press', () => { + const { getByText } = render() + const button = getByText('Get started') + + fireEvent.press(button) + expect(mockNavigate).toHaveBeenCalledWith('/(tabs)') + }) +}) diff --git a/apps/mobile/src/features/Onboarding/Onboarding.container.tsx b/apps/mobile/src/features/Onboarding/Onboarding.container.tsx new file mode 100644 index 0000000000..5a1ba7c431 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/Onboarding.container.tsx @@ -0,0 +1,19 @@ +import React from 'react' +import { OnboardingCarousel } from './components/OnboardingCarousel' +import { items } from './components/OnboardingCarousel/items' +import { useRouter } from 'expo-router' +import { SafeButton } from '@/src/components/SafeButton' + +export function Onboarding() { + const router = useRouter() + + const onGetStartedPress = () => { + router.navigate('/(tabs)') + } + + return ( + + + + ) +} diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.test.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.test.tsx new file mode 100644 index 0000000000..b96f4c9696 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.test.tsx @@ -0,0 +1,21 @@ +import React from 'react' +import { CarouselFeedback } from './CarouselFeedback' +import { render } from '@/src/tests/test-utils' +import darkPalette from '@/src/theme/palettes/darkPalette' + +describe('CarouselFeedback', () => { + it('renders with active state', () => { + const { getByTestId } = render() + + const carouselFeedback = getByTestId('carousel-feedback') + + expect(carouselFeedback.props.style.backgroundColor).toBe(darkPalette.background.default) + }) + + it('renders with inactive state', () => { + const { getByTestId } = render() + const carouselFeedback = getByTestId('carousel-feedback') + + expect(carouselFeedback.props.style.backgroundColor).toBe(darkPalette.primary.light) + }) +}) diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.tsx new file mode 100644 index 0000000000..b3f4491dff --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselFeedback.tsx @@ -0,0 +1,35 @@ +import React, { useEffect } from 'react' +import Animated, { useSharedValue, withSpring } from 'react-native-reanimated' +import { useTheme } from 'tamagui' + +interface CarouselFeedbackProps { + isActive: boolean +} + +const UNACTIVE_WIDTH = 4 +const ACTIVE_WIDTH = 14 + +export function CarouselFeedback({ isActive }: CarouselFeedbackProps) { + const width = useSharedValue(UNACTIVE_WIDTH) + const theme = useTheme() + + useEffect(() => { + if (isActive) { + width.value = withSpring(ACTIVE_WIDTH) + } else { + width.value = withSpring(UNACTIVE_WIDTH) + } + }, [isActive]) + + return ( + + ) +} diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.test.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.test.tsx new file mode 100644 index 0000000000..16c2db7ceb --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.test.tsx @@ -0,0 +1,33 @@ +import React from 'react' +import { CarouselItem } from './CarouselItem' // adjust the import path as necessary +import { Text } from 'tamagui' +import { render } from '@/src/tests/test-utils' + +describe('CarouselItem Component', () => { + it('renders correctly with all props', () => { + const item = { + title: Test Title, + description: 'Test Description', + image: Test Image, + name: 'nevinha', + } + + const { getByText } = render() + + expect(getByText('Test Title')).toBeTruthy() + expect(getByText('Test Description')).toBeTruthy() + expect(getByText('Test Image')).toBeTruthy() + }) + + it('renders correctly without optional props', () => { + const item = { + title: Test Title, + name: 'Test Name', + } + + const { getByText, queryByText } = render() + + expect(getByText('Test Title')).toBeTruthy() + expect(queryByText('Test Description')).toBeNull() // Description is optional and not provided + }) +}) diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.tsx new file mode 100644 index 0000000000..e4d4ac249b --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/CarouselItem.tsx @@ -0,0 +1,28 @@ +import { Text, View, YStack } from 'tamagui' + +export type CarouselItem = { + title: string | React.ReactNode + name: string + description?: string + image?: React.ReactNode +} + +interface CarouselItemProps { + item: CarouselItem +} + +export const CarouselItem = ({ item: { title, description, image } }: CarouselItemProps) => { + return ( + + {image} + + + {title} + + + {description} + + + + ) +} diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.stories.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.stories.tsx new file mode 100644 index 0000000000..bb5fa87761 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.stories.tsx @@ -0,0 +1,25 @@ +import type { Meta, StoryObj } from '@storybook/react' +import React from 'react' +import { OnboardingCarousel } from './OnboardingCarousel' +import { items } from './items' +import { SafeButton } from '@/src/components/SafeButton' +import { action } from '@storybook/addon-actions' + +const meta: Meta = { + title: 'Carousel', + component: OnboardingCarousel, +} + +export default meta + +type Story = StoryObj + +export const Default: Story = { + render: function Render(args) { + return ( + + + + ) + }, +} diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.test.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.test.tsx new file mode 100644 index 0000000000..6dd655e228 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.test.tsx @@ -0,0 +1,24 @@ +import React from 'react' +import { OnboardingCarousel } from './OnboardingCarousel' +import { Text, View } from 'tamagui' +import { render } from '@/src/tests/test-utils' + +describe('OnboardingCarousel', () => { + const items = [ + { name: 'Item1', title: Item1 Title }, + { name: 'Item2', title: Item2 Title }, + { name: 'Item3', title: Item3 Title }, + ] + + // react-native-collapsible-tab-view does not returns any information about the tabs children + // that is why we only test the children component here =/ + it('renders without crashing', () => { + const { getByTestId } = render( + + Child Element + , + ) + + expect(getByTestId('child-element')).toBeTruthy() + }) +}) diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.tsx new file mode 100644 index 0000000000..840acf9956 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/OnboardingCarousel.tsx @@ -0,0 +1,40 @@ +import React, { useState } from 'react' +import { CarouselItem } from './CarouselItem' +import { View } from 'tamagui' +import { Tabs } from 'react-native-collapsible-tab-view' +import { CarouselFeedback } from './CarouselFeedback' + +interface OnboardingCarouselProps { + items: CarouselItem[] + children: React.ReactNode +} + +export function OnboardingCarousel({ items, children }: OnboardingCarouselProps) { + const [activeTab, setActiveTab] = useState(items[0].name) + + return ( + + setActiveTab(event.tabName)} + initialTabName={items[0].name} + renderTabBar={() => <>} + > + {items.map((item, index) => ( + + + + ))} + + + + + {items.map((item) => ( + + ))} + + + {children} + + + ) +} diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/index.ts b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/index.ts new file mode 100644 index 0000000000..cac5baa9a3 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/index.ts @@ -0,0 +1,2 @@ +import { OnboardingCarousel } from './OnboardingCarousel' +export { OnboardingCarousel } diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/items.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/items.tsx new file mode 100644 index 0000000000..012eb6acf5 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingCarousel/items.tsx @@ -0,0 +1,101 @@ +import { Dimensions, StyleSheet } from 'react-native' +import { H1, Image, View } from 'tamagui' +import Signing from '@/assets/images/illustration.png' +import TrackAnywhere from '@/assets/images/anywhere.png' +import { CarouselItem } from './CarouselItem' +import { ParticlesLogo } from '../ParticlesLogo' + +const windowHeight = Dimensions.get('window').height + +const styles = StyleSheet.create({ + image: { + width: '100%', + }, + anywhere: { + height: Math.abs(windowHeight * 0.32), + }, + signing: { + height: Math.abs(windowHeight * 0.3), + }, + textContainer: { + textAlign: 'center', + flexDirection: 'column', + }, +}) + +export const items: CarouselItem[] = [ + { + name: 'multisig', + image: ( + + + + ), + title: ( + <> +

+ Your main +

+

+

+ Safe +

{' '} + multisig + +

+ companion +

+ + ), + }, + { + name: 'tracking', + image: , + title: ( + <> +

+ Track +

+

+ everything. +

+

+ Anywhere. +

+ + ), + description: 'Quickly check your asset balances and portfolio performance anytime, anywhere.', + }, + { + name: 'signing', + image: , + title: ( + <> +

+ Seamless +

+

+ signing +

+ + ), + description: + 'Sign and execute transactions securely from your mobile device. Ensuring your assets are protected, even on the move.', + }, + { + name: 'update-to-date', + image: , + title: ( + <> +

+ Stay +

+

+ up-to-date +

+ + ), + description: + 'Sign and execute transactions securely from your mobile device. Ensuring your assets are protected, even on the move.', + }, +] diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.test.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.test.tsx new file mode 100644 index 0000000000..99232471d4 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.test.tsx @@ -0,0 +1,10 @@ +import React from 'react' +import { OnboardingHeader } from './OnboardingHeader' +import { render } from '@testing-library/react-native' + +test('renders the OnboardingHeader component with the Safe Wallet image', () => { + const { getByLabelText } = render() + + const image = getByLabelText(/Safe Wallet/i) + expect(image).toBeTruthy() +}) diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.tsx b/apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.tsx new file mode 100644 index 0000000000..3a9b18e45e --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingHeader/OnboardingHeader.tsx @@ -0,0 +1,16 @@ +import React from 'react' +import { Image, styled } from 'tamagui' +import SafeWalletLogo from '@/assets/images/safe-wallet.png' +import { SafeAreaView } from 'react-native' + +export const StyledSafeAreaView = styled(SafeAreaView, { + alignItems: 'center', +}) + +export function OnboardingHeader() { + return ( + + + + ) +} diff --git a/apps/mobile/src/features/Onboarding/components/OnboardingHeader/index.ts b/apps/mobile/src/features/Onboarding/components/OnboardingHeader/index.ts new file mode 100644 index 0000000000..ea4b33e18e --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/OnboardingHeader/index.ts @@ -0,0 +1,2 @@ +import { OnboardingHeader } from './OnboardingHeader' +export { OnboardingHeader } diff --git a/apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.test.tsx b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.test.tsx new file mode 100644 index 0000000000..861b813bbc --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.test.tsx @@ -0,0 +1,10 @@ +import { render } from '@/src/tests/test-utils' +import { ParticlesLogo } from './ParticlesLogo' + +describe('ParticlesLogo', () => { + it('should render default markup', () => { + const container = render() + + expect(container).toMatchSnapshot() + }) +}) diff --git a/apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.tsx b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.tsx new file mode 100644 index 0000000000..b344654ab7 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/ParticlesLogo.tsx @@ -0,0 +1,45 @@ +import React from 'react' +import Svg, { Path } from 'react-native-svg' + +export function ParticlesLogo() { + return ( + + + + + + + + + + + + ) +} diff --git a/apps/mobile/src/features/Onboarding/components/ParticlesLogo/__snapshots__/ParticlesLogo.test.tsx.snap b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/__snapshots__/ParticlesLogo.test.tsx.snap new file mode 100644 index 0000000000..fb8cbe4522 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/__snapshots__/ParticlesLogo.test.tsx.snap @@ -0,0 +1,169 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ParticlesLogo should render default markup 1`] = ` + + + + + + + + + + + + + + + +`; diff --git a/apps/mobile/src/features/Onboarding/components/ParticlesLogo/index.ts b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/index.ts new file mode 100644 index 0000000000..41f8265075 --- /dev/null +++ b/apps/mobile/src/features/Onboarding/components/ParticlesLogo/index.ts @@ -0,0 +1,2 @@ +import { ParticlesLogo } from './ParticlesLogo' +export { ParticlesLogo } diff --git a/apps/mobile/src/features/Onboarding/index.ts b/apps/mobile/src/features/Onboarding/index.ts new file mode 100644 index 0000000000..68f4aa89dc --- /dev/null +++ b/apps/mobile/src/features/Onboarding/index.ts @@ -0,0 +1,2 @@ +import { Onboarding } from './Onboarding.container' +export { Onboarding } diff --git a/apps/mobile/src/tests/jest.setup.tsx b/apps/mobile/src/tests/jest.setup.tsx index aa57cd7f5e..8643b5a8d1 100644 --- a/apps/mobile/src/tests/jest.setup.tsx +++ b/apps/mobile/src/tests/jest.setup.tsx @@ -22,6 +22,12 @@ jest.mock('react-native-mmkv', () => ({ }, })) +jest.mock('expo-splash-screen', () => ({ + preventAutoHideAsync: jest.fn(), + setOptions: jest.fn(), + hideAsync: jest.fn(), +})) + jest.mock('redux-persist', () => { const real = jest.requireActual('redux-persist') return {