diff --git a/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/index.tsx b/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/index.tsx index c2c780dbbb..d524f09a56 100644 --- a/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/index.tsx +++ b/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/index.tsx @@ -1,14 +1,13 @@ import React from 'react'; import { scenarioDescription } from './scenario-description'; import { createScenario } from '@apps/tests/shared/helpers'; -import { StyleSheet, Text, View } from 'react-native'; import { StackContainer, - useStackNavigationContext, } from '@apps/shared/gamma/containers/stack'; import { CenteredLayoutView } from '@apps/shared/CenteredLayoutView'; import { Colors } from '@apps/shared/styling'; import { StackNavigationButtons } from '@apps/tests/shared/components/stack-v5/StackNavigationButtons'; +import { StackRouteInformation } from '@apps/tests/shared/components/stack-v5/StackRouteInformation'; function TestStackSimpleNav() { return ; @@ -21,17 +20,32 @@ function StackSetup() { { name: 'Home', Component: HomeScreen, - options: {}, + // Rendering a header (via headerConfig) makes the native back + // button appear on non-root screens, including on Android. The + // root screen (Home) always hides the back button. + options: { + headerConfig: { + title: 'Home', + }, + }, }, { name: 'A', Component: AScreen, - options: {}, + options: { + headerConfig: { + title: 'A', + }, + }, }, { name: 'B', Component: BScreen, - options: {}, + options: { + headerConfig: { + title: 'B', + }, + }, }, ]} /> @@ -41,7 +55,7 @@ function StackSetup() { function HomeScreen() { return ( - + ); @@ -50,7 +64,7 @@ function HomeScreen() { function AScreen() { return ( - + ); @@ -59,29 +73,10 @@ function AScreen() { function BScreen() { return ( - + ); } -function RouteInformation(props: { routeName: string }) { - const routeKey = useStackNavigationContext().routeKey; - - return ( - - Name: {props.routeName} - Key: {routeKey} - - ); -} - -const styles = StyleSheet.create({ - routeInformation: { - color: 'black', - fontSize: 20, - fontWeight: 'bold', - }, -}); - export default createScenario(TestStackSimpleNav, scenarioDescription); diff --git a/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario-description.ts b/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario-description.ts index 4ea629bfd0..d782343d9a 100644 --- a/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario-description.ts +++ b/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario-description.ts @@ -1,7 +1,7 @@ import type { ScenarioDescription } from '@apps/tests/shared/helpers'; export const scenarioDescription: ScenarioDescription = { - name: 'Simple navigation scenario', + name: 'Simple stack navigation', key: 'test-stack-simple-nav', details: 'Test simple push and pop operations', platforms: ['android', 'ios'], diff --git a/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario.md b/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario.md new file mode 100644 index 0000000000..16ba795afc --- /dev/null +++ b/apps/src/tests/single-feature-tests/stack-v5/test-stack-simple-nav/scenario.md @@ -0,0 +1,168 @@ +# Test Scenario: Simple navigation + +## Details + +**Description:** Verify basic push and pop navigation on the gamma/v5 +`StackContainer`. The stack starts with **Home** and can push **A** or **B** +any number of times (including re-pushing a route already on the stack), +each push creating a new screen instance with its own unique `routeKey`; +non-root screens expose a **Pop** button. The test validates that push/pop +via the on-screen buttons, the native header back button, and the +edge-swipe-back / system gesture-back produce +consistent stack state, that `routeKey` values are unique per pushed +instance, and that the root screen (**Home**) cannot be popped. See the +Notes for `routeKey` behavior and how the two platforms are launched +(issue #1459). + +**OS test creation version:** iOS 18.6 and 26.5, Android API Level 36. + +## E2E test + +TBD: Automation is planned and should be straightforward for the +button-driven push/pop steps (similar in scope to the tabs +`test-tabs-simple-nav` suite). Native back button, iOS edge-swipe gesture, +and Android system gesture-back steps may need platform-specific handling +and are not yet implemented. + +## Prerequisites + +- iOS device or simulator +- Android emulator or device + +### iOS launch + +- Run the app normally and navigate to the **Simple stack navigation** + screen (Stack v5) from the in-app scenario selection menu. + +### Android launch + +- To test on Android, run the screen **directly** by editing + [apps/App.tsx](../../../../../App.tsx): import and render + `TestStackSimpleNav` as the root component instead of `Example`, e.g.: + + ```tsx + import { TestStackSimpleNav as Example } from './src/tests/single-feature-tests'; + ``` + + With the gamma `StackContainer` at the root, the Android system + gesture-back pops the stack directly. + +- The Android system gesture-back requires **Gesture navigation** to be + enabled on the emulator/device. If it is not already set, enable it + manually in **Settings → Navigation mode → select Gesture navigation**. + +## Note + +- Each screen shows two labels: `Name` (the route name: `Home`, `A`, or + `B`) and `Key` (the route's unique `routeKey`). Use the `Key` value to + tell apart multiple stacked instances of the same route name. +- `Key` values use a session-global counterthat increments on every push and is **never reset** for + the lifetime of the app session (it is shared across all Stack + containers). Only the **relationships** matter — every push produces a strictly + new `Key`, and a preserved (not recreated) screen keeps the same `Key`. +- **Android:** when the screen is launched **directly** via `App.tsx` (see + the Android launch prerequisite),both the **native header back button** and + the **system gesture-back** work — the same as on iOS. These only fail when the screen + is nested inside the example app's own navigation (issue + [#1459](https://github.com/software-mansion/react-native-screens-labs/issues/1459)), + which is exactly why Android is tested via the direct launch. On both + platforms the on-screen **Pop** button always works. + +## Steps + +### Baseline + +1. Launch the app for the platform under test (see Prerequisites: iOS from + the selection menu, Android directly via `App.tsx`) so the **Home** + screen of the Simple stack navigation is shown. + +- [ ] The **Home** screen is shown with `Name: + Home`, and a `Key`. No back button is visible in + the header. No **Pop** button is shown, only **Push A** and **Push B**. + Note the displayed `Key` value to compare against later steps. + +### Push navigation + +2. Tap **Push A**. + +- [ ] Screen **A** is pushed. Background is light yellow, `Name: A`, and a + `Key` with a new value, distinct from Home's. + A native back button is visible in the header. **Push A**, **Push B**, and **Pop** + buttons are all shown. Note this `Key` value. + +3. While on **A**, tap **Push B**. + +- [ ] Screen **B** is pushed on top of **A**. Background is green, `Name: + B`, and a new `Key`is shown. + A native back button is visible in the header. Note this `Key` value. + +### Re-pushing an already-present route + +4. While on **B**, tap **Push A** again. + +- [ ] A new instance of screen **A** is pushed on top of the stack (stack + is now Home, A, B, A). `Name: A` and a new + `Key` that is **different** from the `Key` shown in step 2. + +### Pop via the on-screen button + +5. Tap **Pop**. + +- [ ] Returns to screen **B**. `Name: B` and the **same** `Key` value + observed in step 3 (the instance was preserved, not recreated). + +6. Tap **Pop** again. + +- [ ] Returns to the original screen **A**. `Name: A` and the **same** `Key` + value observed in step 2. + +7. Tap **Pop** again. + +- [ ] Returns to **Home**. No **Pop** button is shown and no header back + button appears (root screen reached). + +### Native header back button + +8. Tap **Push A**, then tap **Push B**. Then tap the native back button in the +header. + +- [ ] Tapping the native back button behaves the same as tapping **Pop**: + returns to screen **A** with its `Key` unchanged. No crash and no + inconsistent state. + +### Edge-swipe / system gesture-back + +9. While on screen **A** or **B**, swipe from the left screen edge + to the right to trigger the interactive pop gesture. + +- [ ] Completing the swipe/gesture pops the current screen, identical in + effect to tapping **Pop**. The screen below is shown with its original, + unchanged `Key`. +- [ ] Starting the swipe/gesture and releasing before the halfway point + cancels it: the current screen returns to place and no navigation change + occurs. + +### Route key uniqueness (edge case) + +10. From **Home**, tap **Push A**. While on the newly pushed **A**, tap + **Push A** again. While on that new **A**, tap **Push A** once more, + without popping in between. + +- [ ] Three separate **A** instances are stacked. Each shows `Name: A`, + but the `Key` value is different every time you land on a new push. + +### Rapid tapping (edge case) + +11. From any screen, rapidly tap **Push A** several times in quick + succession, before each push transition finishes animating. + +- [ ] Each tap results in exactly one additional **A** screen being + pushed. No crash, no dropped pushes, and no duplicate `Key` values. + +12. From the deepest screen reached in step 11, rapidly tap **Pop** + several times in quick succession, before each pop transition + finishes animating. + +- [ ] The stack pops one screen per completed transition, eventually + stabilizing on **Home**. No crash occurs, and no attempt is made to pop + past the root screen.