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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Unreleased (develop)

- added: Houdini private-send prototype scene (Proposal A) reachable from a wallet's Send button, with hard-coded linked amounts, a recipient-asset picker, a Private send toggle, and modal vs swap-success completion paths.
- added: Remote enable/disable of gift card providers via the info server's giftCardInfo config, supporting whole-provider disabling for Phaze and Bitrefill and per-brand disabling for Phaze.

## 4.49.0 (staging)
Expand Down
85 changes: 85 additions & 0 deletions maestro/14-houdini/houdini-send-a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# Houdini incognito-send prototype walk — Proposal A (From -> To grouping).
#
# Opens the Bitcoin wallet, taps Send (the wallet Send button is routed to the
# prototype scene), and walks every branch. Nothing talks to Houdini; every
# value is hard-coded by HoudiniSendScene. The reroute passes variant 'a1' (the
# "Recipient receives" row is visible before a selection); variant 'a2' hides
# that row until a selection is made.
#
# Screenshots captured (under ~/.maestro/tests/<run>/ ):
# houdini-a-01-plain-initial same-asset start: add-recipient affordance,
# no amount / fee rows yet, "Recipient receives"
# visible (a1)
# houdini-a-02-after-address after a recipient is chosen: You send + Network
# Fee rows appear
# houdini-a-03-incognito incognito on: toggle tile expands with
# messaging, Recipient gets shows conversion %
# houdini-a-04-swap-xmr cross-asset XMR: conversion % + Destination Tag
appId: ${APP_ID}
env:
APP_ID: co.edgesecure.app
PIN_DIGIT: '0'
tags:
- houdini
---
- launchApp
- runFlow:
when:
visible: 'Exit PIN'
commands:
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 900 }
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 900 }
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 900 }
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 1500 }
- runFlow:
when:
visible: 'Security is Our Priority'
commands:
- tapOn: 'Cancel'
# Dismiss the unrelated Stellar/Horizon plugin error toast if present.
- tapOn:
text: '.*Horizon.*'
optional: true

# Open the Bitcoin wallet, then Send (routed to the prototype scene). Gate on
# the wallet tx-list "Receive" button so Send cannot misfire on the home Send.
- tapOn: 'Assets'
- waitForAnimationToEnd:
timeout: 2000
- tapOn: 'My Bitcoin'
- assertVisible: 'Receive'
- tapOn: 'Send'
- waitForAnimationToEnd:
timeout: 3000

# Plain same-asset start: add-recipient affordance, no amount/fee rows yet.
- assertVisible: 'Incognito send'
- assertVisible: 'Send to Address'
- takeScreenshot: houdini-a-01-plain-initial

# Choose a recipient via self-transfer -> reveals the amount + fee rows.
- tapOn:
text: '.*Myself'
- waitForAnimationToEnd:
timeout: 2000
- tapOn: 'My Bitcoin 3'
- waitForAnimationToEnd:
timeout: 2500
- assertVisible: 'You send'
- assertVisible: 'Network Fee'
- takeScreenshot: houdini-a-02-after-address

# Incognito on: toggle tile expands, Recipient gets shows the conversion percent.
- tapOn: 'Incognito send'
- assertVisible: 'Incognito routes your send.*'
- assertVisible: 'Recipient gets'
- takeScreenshot: houdini-a-03-incognito

# Cross-asset: pick XMR (asset mismatch routes through Houdini).
- tapOn: 'Incognito send'
- tapOn: 'Recipient receives'
- tapOn:
text: 'XMR Monero.*'
- assertVisible: 'Monero'
- assertVisible: 'Destination Tag'
- takeScreenshot: houdini-a-04-swap-xmr
66 changes: 66 additions & 0 deletions maestro/14-houdini/houdini-swap-a.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Houdini incognito-swap prototype walk — Proposal A.
#
# Opens the Bitcoin wallet, taps Trade -> "Swap BTC to/from another crypto" (the
# wallet swap action is routed to the prototype HoudiniSwapScene), enters
# amounts with the incognito toggle in a card, then gets a mock quote
# ("Powered by Houdini", no chevron). Nothing talks to Houdini.
#
# Screenshots captured (under ~/.maestro/tests/<run>/ ):
# houdini-swap-01-entry from/to amount entry, incognito toggle in a card
# houdini-swap-02-incognito incognito on: toggle card expands with messaging
# houdini-swap-03-quote mock quote scene, "Powered by Houdini" (no chevron)
appId: ${APP_ID}
env:
APP_ID: co.edgesecure.app
PIN_DIGIT: '0'
tags:
- houdini
---
- launchApp
- runFlow:
when:
visible: 'Exit PIN'
commands:
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 900 }
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 900 }
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 900 }
- tapOn: { text: '${PIN_DIGIT}', waitToSettleTimeoutMs: 1500 }
- tapOn:
text: '.*Horizon.*'
optional: true

# Open the Bitcoin wallet, then Trade -> Swap (routed to the prototype scene).
- tapOn: 'Assets'
- waitForAnimationToEnd:
timeout: 2000
- tapOn: 'My Bitcoin'
- assertVisible: 'Receive'
- tapOn: 'Trade'
- waitForAnimationToEnd:
timeout: 2000
- tapOn: 'Swap BTC to/from another crypto'
- waitForAnimationToEnd:
timeout: 3000

# Swap amount entry, incognito toggle in a card.
- assertVisible: 'You send'
- assertVisible: 'You receive'
- assertVisible: 'Incognito send'
- takeScreenshot: houdini-swap-01-entry

# Incognito on: the toggle card expands with messaging.
- tapOn: 'Incognito send'
- assertVisible: 'Incognito routes your send.*'
- takeScreenshot: houdini-swap-02-incognito

# Slide to get the mock quote -> "Powered by Houdini" (no chevron).
- scrollUntilVisible:
element:
text: 'Slide to get quote'
direction: DOWN
- swipe:
start: 77%, 80%
end: 16%, 80%
duration: 1900
- assertVisible: 'Powered by Houdini'
- takeScreenshot: houdini-swap-03-quote
12 changes: 12 additions & 0 deletions src/components/Main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ import {
} from './scenes/GuiPluginListScene'
import { GuiPluginViewScene as GuiPluginViewSceneComponent } from './scenes/GuiPluginViewScene'
import { HomeScene as HomeSceneComponent } from './scenes/HomeScene'
import { HoudiniSendScene as HoudiniSendSceneComponent } from './scenes/HoudiniSendScene'
import { HoudiniSwapQuoteScene as HoudiniSwapQuoteSceneComponent } from './scenes/HoudiniSwapQuoteScene'
import { HoudiniSwapScene as HoudiniSwapSceneComponent } from './scenes/HoudiniSwapScene'
import { LoanCloseScene as LoanCloseSceneComponent } from './scenes/Loans/LoanCloseScene'
import { LoanCreateConfirmationScene as LoanCreateConfirmationSceneComponent } from './scenes/Loans/LoanCreateConfirmationScene'
import { LoanCreateScene as LoanCreateSceneComponent } from './scenes/Loans/LoanCreateScene'
Expand Down Expand Up @@ -242,6 +245,9 @@ const FioStakingChangeScene = ifLoggedIn(FioStakingChangeSceneComponent)
const FioStakingOverviewScene = ifLoggedIn(FioStakingOverviewSceneComponent)
const GuiPluginViewScene = ifLoggedIn(GuiPluginViewSceneComponent)
const HomeScene = ifLoggedIn(HomeSceneComponent)
const HoudiniSendScene = ifLoggedIn(HoudiniSendSceneComponent)
const HoudiniSwapScene = ifLoggedIn(HoudiniSwapSceneComponent)
const HoudiniSwapQuoteScene = ifLoggedIn(HoudiniSwapQuoteSceneComponent)
const GiftCardAccountInfoScene = ifLoggedIn(GiftCardAccountInfoSceneComponent)
const GiftCardListScene = ifLoggedIn(GiftCardListSceneComponent)
const GiftCardMarketScene = ifLoggedIn(GiftCardMarketSceneComponent)
Expand Down Expand Up @@ -1087,6 +1093,12 @@ const EdgeAppStack: React.FC = () => {
options={{ headerShown: false }}
/>
<AppStack.Screen name="send2" component={SendScene2} />
<AppStack.Screen name="houdiniSend" component={HoudiniSendScene} />
<AppStack.Screen name="houdiniSwap" component={HoudiniSwapScene} />
<AppStack.Screen
name="houdiniSwapQuote"
component={HoudiniSwapQuoteScene}
/>
<AppStack.Screen
name="debugSettings"
component={DebugScene}
Expand Down
Loading
Loading