From a9beeb8ca708bdd2d51d99c002f5ef5dc6685754 Mon Sep 17 00:00:00 2001 From: Jakub Piasecki Date: Mon, 17 Aug 2026 09:44:43 +0200 Subject: [PATCH] [Tests] Add timer e2e test ## Description Updates `Timer` example and adds an e2e argent flow ## Test plan `argent flow run timer-test` --- .argent/flows/timer-test.yaml | 73 +++++++++++++++++++ .../src/new_api/showcase/timer/index.tsx | 36 +++++++-- 2 files changed, 103 insertions(+), 6 deletions(-) create mode 100644 .argent/flows/timer-test.yaml diff --git a/.argent/flows/timer-test.yaml b/.argent/flows/timer-test.yaml new file mode 100644 index 0000000000..d9c4345345 --- /dev/null +++ b/.argent/flows/timer-test.yaml @@ -0,0 +1,73 @@ +steps: + - echo: Launching Expo Example + - launch: com.example.ExpoExample + - await: { visible: { text: "Empty Example" }, timeout: 15000 } + - echo: "On the Home list, search for the timer example" + - type: { text: "timer", into: { id: "search-examples" } } + - echo: "Tap the example to open it" + - tap: { text: "Timer" } + - await: { idle: true } + - await: { visible: { id: "timer-box" } } + + - echo: "Clear console" + - await: { visible: { id: "open-console-button" } } + - tap: { id: "open-console-button" } + - await: { visible: { id: "clear-console-button" } } + - tap: { id: "clear-console-button" } + - tap: { id: "close-console-button" } + - await: { idle: true } + - await: { hidden: { id: "close-console-button" } } + + - echo: "Nothing is measured before the first press" + - assert: { visible: { text: "Last press: none" } } + + - echo: "Hold for two seconds - the measured duration is rounded to whole seconds" + - long-press: { on: { id: "timer-box" }, duration: 2000 } + - await: { visible: { text: "Last press: 2s" } } + + - echo: "Check if console logs are printed in order" + - tap: { id: "open-console-button" } + - await: { idle: true } + - await: { visible: { id: "close-console-button" } } + - assert: { visible: { text: "1. onBegin" } } + - assert: { visible: { text: "2. onActivate" } } + - assert: { visible: { text: "3. onDeactivate" } } + - assert: { visible: { text: "4. onFinalize (2s)" } } + + - echo: "Clear console" + - tap: { id: "clear-console-button" } + - tap: { id: "close-console-button" } + - await: { idle: true } + - await: { hidden: { id: "close-console-button" } } + + - echo: "A longer hold measures a longer duration" + - long-press: { on: { id: "timer-box" }, duration: 4000 } + - await: { visible: { text: "Last press: 4s" } } + + - echo: "Check if console logs are printed in order" + - tap: { id: "open-console-button" } + - await: { idle: true } + - await: { visible: { id: "close-console-button" } } + - assert: { visible: { text: "5. onBegin" } } + - assert: { visible: { text: "6. onActivate" } } + - assert: { visible: { text: "7. onDeactivate" } } + - assert: { visible: { text: "8. onFinalize (4s)" } } + + - echo: "Clear console" + - tap: { id: "clear-console-button" } + - tap: { id: "close-console-button" } + - await: { idle: true } + - await: { hidden: { id: "close-console-button" } } + + - echo: "A tap is too short to activate the gesture, but it is still measured" + - tap: { id: "timer-box" } + - await: { visible: { text: "Last press: 0s" } } + + - echo: "The tap begins and finalizes without activating" + - tap: { id: "open-console-button" } + - await: { idle: true } + - await: { visible: { id: "close-console-button" } } + - assert: { visible: { text: "9. onBegin" } } + - assert: { visible: { text: "10. onFinalize (0s)" } } + - assert: { hidden: { text: "onActivate" } } + - assert: { hidden: { text: "onDeactivate" } } diff --git a/apps/common-app/src/new_api/showcase/timer/index.tsx b/apps/common-app/src/new_api/showcase/timer/index.tsx index 1a73411963..31e583bbaa 100644 --- a/apps/common-app/src/new_api/showcase/timer/index.tsx +++ b/apps/common-app/src/new_api/showcase/timer/index.tsx @@ -1,4 +1,4 @@ -import React, { useRef } from 'react'; +import React, { useState } from 'react'; import { StyleSheet, Text, TextInput, View } from 'react-native'; import { GestureDetector, @@ -14,16 +14,17 @@ import Animated, { useSharedValue, withTiming, } from 'react-native-reanimated'; +import { scheduleOnRN } from 'react-native-worklets'; -import type { FeedbackHandle } from '../../../common'; -import { COLORS, commonStyles, Feedback } from '../../../common'; +import { COLORS, commonStyles, useIndexedLogger } from '../../../common'; const AnimatedTextInput = Animated.createAnimatedComponent(TextInput); export default function TimerExample() { - const feedbackRef = useRef(null); + const [lastPress, setLastPress] = useState('none'); const duration = useSharedValue(0); const colorProgress = useSharedValue(0); + const log = useIndexedLogger(); const animatedProps = useAnimatedProps(() => { return { text: `Duration: ${duration.value.toFixed(2)}s`, @@ -42,6 +43,7 @@ export default function TimerExample() { const longPressGesture = useLongPressGesture({ onBegin: () => { + log('onBegin'); colorProgress.value = withTiming(1, { duration: 150 }); duration.value = 0; duration.value = withTiming(600, { @@ -49,7 +51,17 @@ export default function TimerExample() { easing: Easing.linear, }); }, + onActivate: () => { + log('onActivate'); + }, + onDeactivate: () => { + log('onDeactivate'); + }, onFinalize: () => { + // Rounded, so the summary tolerates press timing jitter. + const seconds = Math.round(duration.value); + log(`onFinalize (${seconds}s)`); + scheduleOnRN(setLastPress, `${seconds}s`); colorProgress.value = withTiming(0, { duration: 300 }); cancelAnimation(duration); }, @@ -66,12 +78,18 @@ export default function TimerExample() { animatedProps={animatedProps} /> - + Hold the box to measure press duration - + + Last press: {lastPress} + + rounded to whole seconds ); @@ -90,4 +108,10 @@ const styles = StyleSheet.create({ textAlign: 'center', fontVariant: ['tabular-nums'], }, + lastPressText: { + marginTop: 8, + fontSize: 16, + fontWeight: '600', + color: COLORS.NAVY, + }, });