Update send summary to show network in a separate card (#21616) (#22067)

* Update send summary to show network in a separate card (#21616)

* Style updates

* Style updates

* Fixes; test updates

* Fixes

* Fixes

* e2e: updated send summary checks

* Spec fix

* Spec fix

* Small schema update

---------

Co-authored-by: Yevheniia Berdnyk <ie.berdnyk@gmail.com>
This commit is contained in:
Alexander
2025-02-25 16:20:17 +01:00
committed by GitHub
co-authored by Yevheniia Berdnyk
parent 5932f7dc99
commit 550602db12
14 changed files with 173 additions and 153 deletions
@@ -14,48 +14,43 @@
(h/describe "Wallet: Summary Info"
(h/test "Type of `status-account` title renders"
(h/render-with-theme-provider [summary-info/view
{:type :status-account
:networks? true
:values {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props status-account-props}])
{:type :status-account
:networks-to-show {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props status-account-props}])
(h/is-truthy (h/get-by-text "Collectibles vault")))
(h/test "Type of `user` title renders"
(h/render-with-theme-provider [summary-info/view
{:type :user
:networks? true
:values {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props {:full-name "M L"
:status-indicator? false
:size :small
:customization-color :blue
:name "Mark Libot"
:address "0x0ah...78b"
:status-account (merge status-account-props
{:size 16})}}])
{:type :user
:networks-to-show {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props {:full-name "M L"
:status-indicator? false
:size :small
:customization-color :blue
:name "Mark Libot"
:address "0x0ah...78b"
:status-account (merge status-account-props
{:size 16})}}])
(h/is-truthy (h/get-by-text "Mark Libot"))
(h/is-truthy (h/get-by-text "Collectibles vault")))
(h/test "Networks true render"
(h/test "Networks specified render"
(h/render-with-theme-provider [summary-info/view
{:type :status-account
:networks? true
:values {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props status-account-props}])
(h/is-truthy (h/get-by-label-text :networks)))
{:type :status-account
:networks-to-show {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props status-account-props}])
(h/is-truthy (h/get-by-label-text :networks))))
(h/test "Networks false render"
(h/describe "Wallet: network summary info"
(h/test "Type of `network` title renders"
(h/render-with-theme-provider [summary-info/view
{:type :status-account
:networks? false
:values {:ethereum 150
:optimism 50
:arbitrum 25}
:account-props status-account-props}])
(h/is-null (h/query-by-label-text :networks))))
{:type :network
:network-props {:full-name "Ethereum"
:network-name :ethereum}}])
(h/is-truthy (h/get-by-text "Ethereum"))))
@@ -5,9 +5,9 @@
[:catn
[:props
[:map
[:type [:enum :status-account :saved-account :account :user :token]]
[:type [:enum :status-account :saved-account :account :user :token :network]]
[:account-props {:optional true} [:maybe :map]]
[:network-props {:optional true} [:maybe :map]]
[:token-props {:optional true} [:maybe :map]]
[:networks? {:optional true} [:maybe :boolean]]
[:values {:optional true} [:maybe :map]]]]]
[:networks-to-show {:optional true} [:maybe :map]]]]]
:any])
@@ -3,13 +3,13 @@
[quo.foundations.colors :as colors]))
(defn container
[networks? theme]
[networks-to-show? theme]
{:width "100%"
:height (if networks? 90 56)
:height (if networks-to-show? 90 56)
:border-radius 16
:border-width 1
:border-color (colors/theme-colors colors/neutral-10 colors/neutral-80 theme)
:margin-bottom (if networks? 4 8)})
:margin-bottom (if networks-to-show? 4 8)})
(def info-container
{:flex-direction :row
@@ -39,3 +39,7 @@
:height 32
:flex-direction :row
:align-items :center})
(def network-icon
{:width 32
:height 32})
@@ -28,50 +28,35 @@
[rn/view
{:style (style/dot-divider theme)}])])
(def ^:private default-token-symbols
{:ethereum "ETH"
:optimism "OP"
:arbitrum "ARB"
:base "ETH"})
(defn networks
[values theme]
(let [{:keys [ethereum optimism arbitrum base]} values
show-optimism? (and optimism
(or (pos? (:amount optimism))
(= (:amount optimism) "<0.01")))
show-arbitrum? (and arbitrum
(or (pos? (:amount arbitrum))
(= (:amount arbitrum) "<0.01")))
show-base? (and base
(or (pos? (:amount base))
(= (:amount base) "<0.01")))]
[rn/view
{:style style/networks-container
:accessibility-label :networks}
(when (and ethereum (pos? (:amount ethereum)))
[network-amount
{:network :ethereum
:amount (str (:amount ethereum) " " (or (:token-symbol ethereum) "ETH"))
:divider? (or show-arbitrum? show-optimism?)
:theme theme}])
(when show-optimism?
[network-amount
{:network :optimism
:amount (str (:amount optimism) " " (or (:token-symbol optimism) "OETH"))
:divider? show-arbitrum?
:theme theme}])
(when show-arbitrum?
[network-amount
{:network :arbitrum
:amount (str (:amount arbitrum) " " (or (:token-symbol arbitrum) "ARB"))
:theme theme}])
(when show-base?
[network-amount
{:network :base
:amount (str (:amount base) " " (or (:token-symbol base) "ETH"))
:theme theme}])]))
[networks-to-show theme]
(->> networks-to-show
(map-indexed
(fn [i [k {:keys [amount token-symbol]}]]
(when (or (pos? amount)
(= amount "<0.01"))
[network-amount
{:network k
:amount (str amount " " (or token-symbol (get default-token-symbols k)))
:divider? (not= (dec i) (-> networks-to-show keys count))
:theme theme}])))
(remove nil?)
(into [rn/view
{:style style/networks-container
:accessibility-label :networks}])))
(defn- view-internal
[{:keys [type account-props token-props networks? values]}]
[{:keys [type account-props network-props token-props networks-to-show]}]
(let [theme (quo.theme/use-theme)
address (or (:address account-props) (:address token-props))]
[rn/view
{:style (style/container networks? theme)}
{:style (style/container (seq? networks-to-show) theme)}
[rn/view
{:style style/info-container}
(case type
@@ -82,16 +67,26 @@
(assoc account-props
:size :size-32
:neutral? true)]
:network [rn/image
{:source (resources/get-network (:network-name network-props))
:style style/network-icon}]
[user-avatar/user-avatar account-props])
[rn/view {:style {:margin-left 8}}
(when (not= type :account)
[text/text {:weight :semi-bold} (or (:name account-props) (:label token-props))])
(when (not (some #{type} [:account :network]))
[text/text
{:weight :semi-bold}
(or (:name account-props) (:label token-props))])
(when (= type :network)
[text/text
{:weight :semi-bold}
(:full-name network-props)])
[rn/view
{:style {:flex-direction :row
:align-items :center}}
(when (= type :user)
[:<>
[rn/view {:style {:margin-right 4}} [account-avatar/view (:status-account account-props)]]
[rn/view {:style {:margin-right 4}}
[account-avatar/view (:status-account account-props)]]
[text/text
{:size :paragraph-2
:style {:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)}}
@@ -105,10 +100,10 @@
:style {:color (when (not= type :account)
(colors/theme-colors colors/neutral-50 colors/neutral-40 theme))}}
address])]]]
(when networks?
(when networks-to-show
[:<>
[rn/view
{:style (style/line-divider theme)}]
[networks values theme]])]))
[networks networks-to-show theme]])]))
(def view (schema/instrument #'view-internal summary-info-schema/?schema))
@@ -12,17 +12,15 @@
:options [{:key :status-account}
{:key :user}
{:key :saved-account}
{:key :account}]}
{:key :networks? :type :boolean}])
{:key :account}]}])
(defn view
[]
(let [state (reagent/atom {:type :status-account
:networks? true
:values {:ethereum {:amount 150}
:optimism {:amount 50}
:arbitrum {:amount 25}}})
(let [state (reagent/atom {:type :status-account
:networks-to-show {:ethereum {:amount 150}
:optimism {:amount 50}
:arbitrum {:amount 25}}})
status-account-props {:customization-color :purple
:size 32
:emoji "🍑"
@@ -28,3 +28,7 @@
[theme]
{:margin-bottom 8
:color (colors/theme-colors colors/neutral-50 colors/neutral-40 theme)})
(def summary-container
{:padding-horizontal 20
:padding-bottom 16})
@@ -135,9 +135,7 @@
:saved-address :saved-account
:account :status-account
summary-type)]
[rn/view
{:style {:padding-horizontal 20
:padding-bottom 16}}
[rn/view {:style style/summary-container}
[quo/text
{:size :paragraph-2
:weight :medium
@@ -145,17 +143,32 @@
:accessibility-label accessibility-label}
label]
[quo/summary-info
{:type summary-info-type
:networks? true
:values (send-utils/network-values-for-ui network-values)
:account-props (cond-> account-props
(and account-to? (not bridge-tx?))
(assoc
:size 32
:name (:label recipient)
:full-name (:label recipient)
:emoji (:emoji recipient)
:customization-color (:customization-color recipient)))}]]))
{:type summary-info-type
:networks-to-show (when bridge-tx?
(send-utils/network-values-for-ui network-values))
:account-props (cond-> account-props
(and account-to? (not bridge-tx?))
(assoc
:size 32
:name (:label recipient)
:full-name (:label recipient)
:emoji (:emoji recipient)
:customization-color (:customization-color recipient)))}]]))
(defn- network-summary
[{:keys [theme label accessibility-label]}]
(let [network (rf/sub [:wallet/send-selected-network])]
(when network
[rn/view {:style style/summary-container}
[quo/text
{:size :paragraph-2
:weight :medium
:style (style/section-label theme)
:accessibility-label accessibility-label}
label]
[quo/summary-info
{:type :network
:network-props network}]])))
(defn- data-item
[{:keys [title subtitle]}]
@@ -300,6 +313,7 @@
:accessibility-label :summary-from-label
:label (i18n/label :t/from-capitalized)
:account-props from-account-props
:bridge-tx? (= transaction-type :tx/bridge)
:theme theme}]
[user-summary
{:summary-type (if (= transaction-type :tx/bridge)
@@ -313,4 +327,8 @@
:recipient recipient
:bridge-tx? (= transaction-type :tx/bridge)
:account-to? true
:theme theme}]]]]))
:theme theme}]
(when-not (= transaction-type :tx/bridge)
[network-summary
{:label (i18n/label :t/on-capitalized)
:theme theme}])]]]))
@@ -24,7 +24,7 @@
{:size :paragraph-2
:weight :medium
:style style/on}
(i18n/label :t/on-uppercase)]
(i18n/label :t/on-capitalized)]
[quo/context-tag
{:type :network
:network-logo (:logo-url provider)
@@ -75,14 +75,13 @@
:accessibility-label title-accessibility-label}
label]
[quo/summary-info
{:type :token
:networks? true
:values (send-utils/network-values-for-ui network-values)
:token-props {:token token-symbol
:label (str amount " " token-symbol)
:address (when token-address
(address-utils/get-shortened-compressed-key token-address))
:size 32}}]]))
{:type :token
:token-props {:token token-symbol
:label (str amount " " token-symbol)
:address (when token-address
(address-utils/get-shortened-compressed-key token-address))
:size 32}
:networks-to-show (send-utils/network-values-for-ui network-values)}]]))
(defn- pay-section
[]
+9
View File
@@ -71,3 +71,12 @@
{:amount amount-fixed :token-symbol token-symbol})))
{}
network-values))))
(re-frame/reg-sub
:wallet/send-selected-network
:<- [:wallet/wallet-send]
(fn [{:keys [to-values-by-chain]}]
(-> to-values-by-chain
keys
first
network-utils/get-network-details)))
@@ -36,11 +36,12 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
'').lower()
self.receiver_short_address = self.receiver['wallet_address'].replace(self.receiver['wallet_address'][6:-3],
'').lower()
self.network_name = 'Base'
@marks.testrail_id(741839)
def test_wallet_collectibles_balance(self):
self.wallet_view.collectibles_tab.click()
self.wallet_view.set_network_in_wallet('Base')
self.wallet_view.set_network_in_wallet(self.network_name)
collectibles = {
"BVL": {"quantity": 2,
"info": {"Account": "Account 1",
@@ -103,15 +104,17 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
self.wallet_view.get_collectible_element('BVL').click()
self.wallet_view.amount_input_increase_button.click()
self.wallet_view.confirm_button.click()
expected_text = '2 BVL #47'
for text in [self.account_name, self.sender_short_address, expected_text]:
for text in [self.account_name, self.sender_short_address]:
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown in 'From' container on the Review Send page" % text)
for text in [self.receiver_short_address, expected_text]:
if not self.wallet_view.to_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown in 'To' container on the Review Send page" % text)
"Text %s is not shown inside 'From' container on the Review Send page" % text)
if not self.wallet_view.to_data_container.get_child_element_by_text(
self.receiver_short_address).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown inside 'To' container on the Review Send page" % text)
if not self.wallet_view.on_data_container.get_child_element_by_text(self.network_name).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown inside 'On' container on the Review Send page" % text)
data_to_check = {
'Est. time': ' min',
'Max fees': r"[$]\d+.\d+",
@@ -148,15 +151,17 @@ class TestWalletCollectibles(MultipleSharedDeviceTestCase):
self.wallet_view.send_from_collectible_info_button.click()
self.wallet_view.address_text_input.send_keys(self.receiver['wallet_address'])
self.wallet_view.continue_button.click()
expected_text = '1 Glitch Punks #3422'
for text in [self.account_name, self.sender_short_address, expected_text]:
for text in [self.account_name, self.sender_short_address]:
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown in 'From' container on the Review Send page" % text)
for text in [self.receiver_short_address, expected_text]:
if not self.wallet_view.to_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown in 'To' container on the Review Send page" % text)
if not self.wallet_view.to_data_container.get_child_element_by_text(
self.receiver_short_address).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown in 'To' container on the Review Send page" % text)
if not self.wallet_view.on_data_container.get_child_element_by_text(self.network_name).is_element_displayed():
self.errors.append(self.wallet_view,
"Text %s is not shown inside 'On' container on the Review Send page" % text)
data_to_check = {
'Est. time': ' min',
'Max fees': r"[$]\d+.\d+",
@@ -99,28 +99,32 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
self.wallet_view.confirm_button.click()
self.wallet_view.just_fyi("Checking Review Send page for %s on %s" % (asset, network))
expected_amount = "%s %s" % (data['amount'], 'ETH' if asset == 'Ether' else 'SNT')
sender_short_address = self.sender['wallet_address'].replace(self.sender['wallet_address'][6:-3],
'').lower()
receiver_short_address = self.receiver['wallet_address'].replace(self.receiver['wallet_address'][6:-3],
'').lower()
for text in [self.account_name, sender_short_address, expected_amount]:
for text in [self.account_name, sender_short_address]:
if not self.wallet_view.from_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s on %s: text %s is not shown in 'From' container on the Review Send page" % (
asset, network, text))
for text in [receiver_short_address, expected_amount]:
if not self.wallet_view.to_data_container.get_child_element_by_text(text).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s on %s: text %s is not shown in 'To' container on the Review Send page" % (
asset, network, text))
if not self.wallet_view.to_data_container.get_child_element_by_text(
receiver_short_address).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s on %s: text %s is not shown in 'To' container on the Review Send page" % (
asset, network, text))
if not self.wallet_view.on_data_container.get_child_element_by_text(network).is_element_displayed():
self.errors.append(
self.wallet_view,
"%s on %s: network %s is not shown in 'On' container on the Review Send page" % (
asset, network, text))
data_to_check = {
'Est. time': ' min',
'Max fees': r"[$]\d+.\d+",
'Recipient gets': expected_amount
'Recipient gets': "%s %s" % (data['amount'], 'ETH' if asset == 'Ether' else 'SNT')
}
for key, expected_value in data_to_check.items():
try:
@@ -305,17 +309,6 @@ class TestWalletOneDevice(MultipleSharedDeviceTestCase):
self.wallet_view,
"%s to %s: Text %s is not shown in the '%s' data container on the Review Bridge screen"
% (network_from, network_to, text, name))
amount_text = container.amount_text
if name == 'from' and amount_text != amount + ' ETH':
self.errors.append(
self.wallet_view,
"%s to %s: amount %s in the 'from' data container doesn't match expected %s ETH"
% (network_from, network_to, amount_text, amount))
if name == 'to' and not re.findall(r"0.000\d+ ETH", amount_text):
self.errors.append(
self.wallet_view,
"%s to %s: amount %s in the 'to' data container is not a number"
% (network_from, network_to, amount_text))
except TimeoutException:
self.errors.append(self.wallet_view, "%s to %s: data '%s' is not shown in Review Bridge screen" %
(network_from, network_to, name))
+4 -3
View File
@@ -81,7 +81,7 @@ class ActivityElement(BaseElement):
class ConfirmationViewInfoContainer(BaseElement):
def __init__(self, driver, label_name: str):
self.locator = "//*[@content-desc='summary-%s-label']/following-sibling::android.view.ViewGroup[1]" % label_name
self.locator = "//*[@text='%s']/following-sibling::android.view.ViewGroup[1]" % label_name
super().__init__(driver, xpath=self.locator)
@property
@@ -139,8 +139,9 @@ class WalletView(BaseView):
self.amount_input_increase_button = Button(self.driver, accessibility_id='amount-input-inc-button')
# Review Send and Review Bridge screens
self.from_data_container = ConfirmationViewInfoContainer(self.driver, label_name='from')
self.to_data_container = ConfirmationViewInfoContainer(self.driver, label_name='to')
self.from_data_container = ConfirmationViewInfoContainer(self.driver, label_name='From')
self.to_data_container = ConfirmationViewInfoContainer(self.driver, label_name='To')
self.on_data_container = ConfirmationViewInfoContainer(self.driver, label_name='On')
# Swap flow
self.approve_swap_button = Button(self.driver, accessibility_id='Approve')
-1
View File
@@ -1892,7 +1892,6 @@
"on-keycard": "On Keycard",
"on-status-tree": "On Status tree",
"on-the-web": "On the web",
"on-uppercase": "On",
"once-enabled-share-metadata": "Once enabled, links posted in the chat may share your metadata with the site",
"one-day": "One day",
"one-month": "One month",