Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions apps/src/tests/component-integration-tests/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ import OrientationScenarioGroup from './orientation';
import ScrollViewScenarioGroup from './scroll-view';
import FormSheetScenarioGroup from './form-sheet';
import TabsInStackV5ScenarioGroup from './tabs-stack-v5';
import SvmScenarioGroup from './scroll-view-marker';
import ScenarioSelectionScreen from '@apps/tests/shared/ScenarioScreen';

export const COMPONENT_SCENARIOS = {
Orientation: OrientationScenarioGroup,
ScrollView: ScrollViewScenarioGroup,
FormSheet: FormSheetScenarioGroup,
TabsInStackV5: TabsInStackV5ScenarioGroup,
ScrollViewMarker: SvmScenarioGroup,
} as const;

type ParamsList = { [k: keyof typeof COMPONENT_SCENARIOS]: undefined } & {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import type { ScenarioGroup } from '@apps/tests/shared/helpers';
import TestSvmTabsScrollEdgeEffects from './test-svm-tabs-scroll-edge-effects';
import TestStackSvmTabsSpecialEffects from './test-stack-svm-tabs-special-effects';

const scenarios = {
TestSvmTabsScrollEdgeEffects,
TestStackSvmTabsSpecialEffects,
};

const TestSvmScenarioGroup: ScenarioGroup<keyof typeof scenarios> = {
name: 'ScrollViewMarker Integration Tests',
details: 'Test interaction between ScrollViewMarker and various components',
scenarios,
};

export default TestSvmScenarioGroup;
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
import { createScenario } from '@apps/tests/shared/helpers';
import React from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import { scenarioDescription } from './scenario-description';
import {
DEFAULT_TAB_ROUTE_OPTIONS,
type TabRouteConfig,
TabsContainer,
useTabsNavigationContext,
} from '@apps/shared/gamma/containers/tabs';
import { Colors } from '@apps/shared/styling';
import { Rectangle } from '@apps/shared/Rectangle';
import { ScrollViewMarker } from 'react-native-screens/experimental';
import { type ScrollEdgeEffect } from 'react-native-screens';
import {
StackContainer,
type StackRouteConfig,
} from '@apps/shared/gamma/containers/stack';

export function TestStackSvmTabsSpecialEffects() {
return <TabsNavigation />;
}

const TABS_ROUTE_CONFIGS: TabRouteConfig[] = [
{
name: 'Home',
Component: TabContents,
options: {
...DEFAULT_TAB_ROUTE_OPTIONS,
title: 'Home',
},
},
{
name: 'Stack',
Component: StackTabScreen,
options: {
...DEFAULT_TAB_ROUTE_OPTIONS,
title: 'Stack',
},
},
];

const STACK_ROUTE_CONFIGS: StackRouteConfig[] = [
{
name: 'First',
Component: StackContents,
options: {},
},
{
name: 'Second',
Component: StackContents,
options: {},
},
];

function TabContents() {
const edgeEffectStyle: ScrollEdgeEffect =
useTabsNavigationContext().routeKey === 'Home' ? 'hard' : 'soft';

return (
<View style={[{ backgroundColor: Colors.BlueLight20 }, styles.fillParent]}>
<ScrollViewMarker
style={styles.fillParent}
scrollEdgeEffects={{ top: 'hidden', bottom: edgeEffectStyle }}>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.fillParent}>
<ScrollViewContents />
</ScrollView>
</ScrollViewMarker>
</View>
);
}

function StackContents() {
return (
<View style={[{ backgroundColor: Colors.BlueLight20 }, styles.fillParent]}>
<HeuristicBreakingView />
<ScrollViewMarker
style={styles.fillParent}
scrollEdgeEffects={{ top: 'hidden', bottom: 'hard' }}>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.fillParent}>
<ScrollViewContents />
</ScrollView>
</ScrollViewMarker>
</View>
);
}

function TabsNavigation() {
return <TabsContainer routeConfigs={TABS_ROUTE_CONFIGS} />;
}

function StackTabScreen() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aren't we missing export or is this intentional?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are coming back to state where we will export only App() (now it should be renamed) and default export createScenario()
#4201

return <StackContainer routeConfigs={STACK_ROUTE_CONFIGS} />;
}

function ScrollViewContents(props: { elementCount?: number }) {
const elementCount = props.elementCount ?? 48;
return (
<>
{Array.from({ length: elementCount }).map((_, index) => {
return (
<View key={index.toString()} style={[{ width: '100%' }]}>
<Rectangle
key={index.toString()}
color={Colors.RedDark100}
width={'100%'}
height={128}
/>
<View style={[{ width: '100%', height: 12 }]} />
</View>
);
})}
</>
);
}

function HeuristicBreakingView() {
return <View collapsable={false} style={{ width: '100%', height: 0 }}></View>;
}

export default createScenario(TestStackSvmTabsSpecialEffects, scenarioDescription);

const styles = StyleSheet.create({
fillParent: {
flex: 1,
width: '100%',
height: '100%',
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ScenarioDescription } from '@apps/tests/shared/helpers';

export const scenarioDescription: ScenarioDescription = {
name: 'SVM in Stack & Tabs - tabs special effects',
key: 'test-stack-svm-tabs-special-effects',

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Im not sure if the name shouldn't be like this:

Suggested change
key: 'test-stack-svm-tabs-special-effects',
key: 'test-svm-in-stack-tabs-special-effects',

It's what I assumed from scenario name. If I'm right, please rename also test directory.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no, that would be against naming convention IIRC.
The name is alright IMO.

details:
'Test whether special effects (on tab repetition) are performed correctly in nested container scenario ' +
'(stack in tabs)',
platforms: ['ios', 'android'],
e2eCoverage: 'tbd',
smokeTest: false,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Test Scenario: SVM in Stack & Tabs - tabs special effects

## Details

**Description:**
This test verifies interaction between `ScrollViewMarker`, `Stack` and `Tabs` components.
The primary goal is to verify that the tabs special effects (scroll-to-top, pop-to-top) do work in
nested container scenario.

**OS test creation version:**
iOS: 26.5, Android: API Level 36.

## E2E test

TBD

## Prerequisites

- iOS: simulator with iOS 15+ is enough,
- Android: emulator

## Note

Android part of the code is unimplemented yet, therefore it is expected not to work.

iOS implementation doesn't currently support nested container interaction yet.
This test needs to be updated after such interaction is supported.
Comment on lines +24 to +27

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting:

Suggested change
Android part of the code is unimplemented yet, therefore it is expected not to work.
iOS implementation doesn't currently support nested container interaction yet.
This test needs to be updated after such interaction is supported.
- Android part of the code is unimplemented yet, therefore it is expected not to work.
- iOS implementation doesn't currently support nested container interaction yet.
- This test needs to be updated after such interaction is supported.


## Steps

1. Launch the app and navigate to the **SVM in Stack & Tabs - tabs special effects** screen.

- [ ] There should be two tabs: `Home` and `Stack`.
- [ ] `Home` tab should be selected.

2. Scrolldown a bit.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: scroll down


Doesn't really matter how much you scroll - the distance should be "noticeable".
Comment thread
LKuchno marked this conversation as resolved.

3. Press `Home` tab item (repeated tab selection) to trigger the special effect.

- [ ] *scroll-top-top* should be triggered and you should observe the scroll-view scrolling
to it's top.
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import { createScenario } from '@apps/tests/shared/helpers';
import React from 'react';
import { ScrollView, StyleSheet, View } from 'react-native';
import { scenarioDescription } from './scenario-description';
import {
DEFAULT_TAB_ROUTE_OPTIONS,
type TabRouteConfig,
TabsContainer,
useTabsNavigationContext,
} from '@apps/shared/gamma/containers/tabs';
import { Colors } from '@apps/shared/styling';
import { Rectangle } from '@apps/shared/Rectangle';
import { ScrollViewMarker } from 'react-native-screens/experimental';
import { type ScrollEdgeEffect } from 'react-native-screens';

export function TestSvmTabsScrollEdgeEffects() {
return <TabsNavigation />;
}

const TABS_ROUTE_CONFIGS: TabRouteConfig[] = [
{
name: 'Home',
Component: TabContents,
options: {
...DEFAULT_TAB_ROUTE_OPTIONS,
title: 'Home',
},
},
{
name: 'Second',
Component: TabContents,
options: {
...DEFAULT_TAB_ROUTE_OPTIONS,
title: 'Second',
},
},
];

function TabContents() {
const edgeEffectStyle: ScrollEdgeEffect =
useTabsNavigationContext().routeKey === 'Home' ? 'hard' : 'soft';

return (
<View style={[{ backgroundColor: Colors.BlueLight20 }, styles.fillParent]}>
<HeuristicBreakingView />
<ScrollViewMarker
style={styles.fillParent}
scrollEdgeEffects={{ top: 'hidden', bottom: edgeEffectStyle }}>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={styles.fillParent}>
<ScrollViewContents />
</ScrollView>
</ScrollViewMarker>
</View>
);
}

function TabsNavigation() {
return <TabsContainer routeConfigs={TABS_ROUTE_CONFIGS} />;
}

function ScrollViewContents(props: { elementCount?: number }) {
const elementCount = props.elementCount ?? 48;
return (
<>
{Array.from({ length: elementCount }).map((_, index) => {
return (
<View key={index.toString()} style={[{ width: '100%' }]}>
<Rectangle
key={index.toString()}
color={Colors.RedDark100}
width={'100%'}
height={128}
/>
<View style={[{ width: '100%', height: 12 }]} />
</View>
);
})}
</>
);
}

function HeuristicBreakingView() {
return <View collapsable={false} style={{ width: '100%', height: 0 }}></View>;
}

export default createScenario(TestSvmTabsScrollEdgeEffects, scenarioDescription);

const styles = StyleSheet.create({
fillParent: {
flex: 1,
width: '100%',
height: '100%',
},
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { ScenarioDescription } from '@apps/tests/shared/helpers';

export const scenarioDescription: ScenarioDescription = {
name: 'SVM in Tabs - scroll edge effects',
key: 'test-svm-tabs-scroll-edge-effects',
details:
'Test whether scroll edge effects are applied correctly when ScrollViewMarker ' +
'is used inside Tabs',
platforms: ['ios'],
e2eCoverage: 'tbd',
smokeTest: false,
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Test Scenario: Integration: SVM in Tabs - scroll edge effects

## Details

**Description:**
This test verifies interaction between `ScrollViewMarker` and `Tabs` in scope of scroll-edge-effects.
It allows to test both whether the scroll-edge-effect is correctly applied AND whether it is correctly
updated between different tabs.

**OS test creation version:**
iOS 26.5

## E2E test

TBD

## Prerequisites

iOS: simulator with iOS 26+ is enough,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: ,


## Note

Seemingly the edge effect is applied correctly no matter the integration with the scrollview marker.
Likely UITabBarController uses some different logic to UIViewController.contentScrollView to detect scrollview,
because even when I have had returned nil from the method, the edge effect had still been applied.
Nevertheless, I decided to include this test case here, just to make sure it works.
Also this allows us to test that different ScrollViewMarkers from different tab update the edge effect correctly on tab change.

## Steps

1. Launch the app and navigate to the **SVM in Tabs - scroll edge effects** screen.

- [ ] There should be two tabs: `Home` and `Second`.
- [ ] `Home` tab should be selected.
- [ ] `Hard` scroll-edge-effect should be applied (opqaue background of tab bar).

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can expand a bit on what is expected for Hard:

Suggested change
- [ ] `Hard` scroll-edge-effect should be applied (opqaue background of tab bar).
- [ ] `Hard` scroll-edge-effect should be applied (opaque background of tab bar with a hard cutoff and dividing line).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Dividing line? I haven't noticed such. Will take another look later 😄

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's actually taken from 'hard' scroll-edge-effect documentation I interpret it as visible cutoff tab bar 😅


2. Change tab to `Second`.

- [ ] The scroll-edge-effect should be now changed to `soft` after/during the transition.

3. Change tab back to the `Home`.

- [ ] The scroll-edge-effect should be back at `hard`.
Loading
Loading