diff --git a/FabricExample/e2e/single-feature-tests/tabs/test-tabs-simple-nav.e2e.ts b/FabricExample/e2e/single-feature-tests/tabs/test-tabs-simple-nav.e2e.ts new file mode 100644 index 0000000000..84cf1995d9 --- /dev/null +++ b/FabricExample/e2e/single-feature-tests/tabs/test-tabs-simple-nav.e2e.ts @@ -0,0 +1,79 @@ +import { device, expect, element, by } from 'detox'; +import { + forceTapByLabeliOS, + selectSingleFeatureTestsScreen, +} from '../../e2e-utils'; + +describe('@smoke Tabs: simple navigation', () => { + beforeAll(async () => { + await device.reloadReactNative(); + await selectSingleFeatureTestsScreen('Tabs', 'test-tabs-simple-nav'); + }); + + it('should display First tab as active by default', async () => { + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); + + it('should navigate to Second tab via tab bar', async () => { + await element(by.id('tab-bar-item-second')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('Second'); + }); + + it('should navigate to Third tab via tab bar', async () => { + await element(by.id('tab-bar-item-third')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('Third'); + }); + + it('should navigate back to First tab via tab bar', async () => { + await element(by.id('tab-bar-item-first')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); + + it('should navigate to Second tab programmatically via Select Second button', async () => { + await element(by.id('select-second-button')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('Second'); + }); + + it('should navigate to Third tab programmatically via Select Third button', async () => { + await element(by.id('select-third-button')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('Third'); + }); + + it('should navigate to First tab programmatically via Select First button', async () => { + await element(by.id('select-first-button')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); + + it('should skip Second tab when navigating directly from First to Third programmatically', async () => { + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + await element(by.id('select-third-button')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('Third'); + }); + + it('should skip Second tab when navigating directly from Third to First via tab bar', async () => { + await expect(element(by.id('route-key-label'))).toHaveLabel('Third'); + await element(by.id('tab-bar-item-first')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); + + it('should navigate correctly after mixing tab-bar and programmatic navigation', async () => { + await element(by.id('tab-bar-item-second')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('Second'); + await element(by.id('select-first-button')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); + + it('should stay on First tab when re-tapping the active First tab bar item', async () => { + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + device.getPlatform() === 'ios' + ? await forceTapByLabeliOS('FirstTab') + : await element(by.id('tab-bar-item-first')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); + + it('should stay on First tab when calling selectTab on the already-active tab programmatically', async () => { + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + await element(by.id('select-first-button')).tap(); + await expect(element(by.id('route-key-label'))).toHaveLabel('First'); + }); +}); diff --git a/apps/src/tests/single-feature-tests/tabs/index.ts b/apps/src/tests/single-feature-tests/tabs/index.ts index 3e35629810..f85db2644c 100644 --- a/apps/src/tests/single-feature-tests/tabs/index.ts +++ b/apps/src/tests/single-feature-tests/tabs/index.ts @@ -22,6 +22,8 @@ import TestTabsSystemItem from './test-tabs-system-item-ios'; import TestTabsGeneralAppearanceNoLiquidGlass from './test-tabs-general-appearance-no-liquid-glass-ios'; import TestTabsNativeContainerStyle from './test-tabs-native-container-style'; +export { TestTabsSimpleNav } from './test-tabs-simple-nav'; + const scenarios = { TestTabBottomAccessory, TestTabsOverrideScrollViewContentInset, diff --git a/apps/src/tests/single-feature-tests/tabs/test-tabs-simple-nav/index.tsx b/apps/src/tests/single-feature-tests/tabs/test-tabs-simple-nav/index.tsx index 7ce4f52b62..8ade3d8768 100644 --- a/apps/src/tests/single-feature-tests/tabs/test-tabs-simple-nav/index.tsx +++ b/apps/src/tests/single-feature-tests/tabs/test-tabs-simple-nav/index.tsx @@ -10,11 +10,13 @@ import { } from '@apps/shared/gamma/containers/tabs'; import { CenteredLayoutView } from '@apps/shared/CenteredLayoutView'; -export function ContentView() { +function ContentView() { const { routeKey } = useTabsNavigationContext(); return ( - + {routeKey} @@ -22,14 +24,26 @@ export function ContentView() { ); } -export function TabsNavigationButtons() { +function TabsNavigationButtons() { const nav = useTabsNavigationContext(); return ( -