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.