Page MenuHomePhabricator

[Cashtab] Show liquid XEC and XECX amounts under combined balance
ClosedPublic

Authored by bytesofman on Mon, Jul 20, 21:07.

Details

Summary

Improve visibility of XEC + XECX split. User can tap card to toggle between combined and split balances. Also tooltip on hover (web and extension).

Test Plan

npm test

Diff Detail

Repository
rABC Bitcoin ABC
Lint
Lint Not Applicable
Unit
Tests Not Applicable

Event Timeline

There are a very large number of changes, so older changes are hidden. Show Older Changes

Stack liquid XEC / Staked in monospace with aligned place values.
Omit redundant USD fiat line on the Firma card when fiat currency is USD.

Revert to % staked + info icon; tooltip shows liquid XEC / XECX on hover (web/extension) or tap (Android).
Omit XEC/XECX decimals above 10k; Firma USD uses 2 decimals above $0.01.

Stacked aligned XEC/XECX tooltip; only the "staked" word links to XECX; the rest of the row toggles the tooltip.

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Drop tooltip. Tap eCash card to expand stacked XEC/XECX and hide USD + % staked; "staked" still links to XECX.

Drop tooltip. Tap eCash card to expand stacked XEC/XECX and hide USD + % staked; "staked" still links to XECX.
Revert accidental 5.20.0 version bump from local android build.

Tap eCash card only swaps combined total/fiat for stacked XEC/XECX; keep USD card and % staked visible.

Tap eCash card only swaps combined total/fiat for stacked XEC/XECX; keep USD card and % staked visible.
Revert accidental 5.20.0 version bump from local android build.

Fix toggle height jump: fixed-height balance slot and smaller stacked XEC/XECX font.

Shrink stacked XEC/XECX monospace further to stop toggle height jump.

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Restore stacked XEC/XECX hover tooltip on web and extension (Android keeps tap-to-expand only).

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Fix web tooltip (use app-wide cashtab-tooltip) and lock toggle height (CSS calc was invalid because line-height vars are unitless).

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Show stacked XEC/XECX tooltip on hover anywhere on the eCash card.

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <Etokens /> Large token list is rendered and searchable ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/Etokens.test.tsx:61:59)
====== CashTab Unit Tests: <Etokens /> Collections filter shows parent collection when user holds NFT but not collection token ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/Etokens.test.tsx:188:59)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params
CashTab Unit Tests: <Etokens /> Large token list is rendered and searchable
CashTab Unit Tests: <Etokens /> Collections filter shows parent collection when user holds NFT but not collection token

Fix tests for combined XEC+XECX header totals and >10k no-decimals (Agora, SendByUrlParams). Add dedicated Header test for tap-to-expand / collapse and staked-link non-toggle.

Failed tests logs:

====== CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  100,000.00
Received:
  100,000
    at Object.toHaveTextContent (/work/cashtab/src/components/Agora/__tests__/index.test.tsx:913:57)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1226:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,970.81
Received:
  1,009,971
    at Object.toHaveTextContent (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:1337:11)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <Etokens /> Large token list is rendered and searchable ======
TestingLibraryElementError: Unable to find an element with the title: Token List Item.

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-kAzzGY bFOoJn"
      title="Loading..."
    >
      <div
        class="sc-cSHVUG kmQSTX"
        title="Loading"
      >
        <div />
        <div />
        <div />
        <div />
      </div>
    </div>
    <div
      class="sc-jbWsrJ dmgmcX"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-hqGPoI jLOaEj"
      >
        <div
          class="sc-imAxmJ gKMUad"
        >
          <div
            class="sc-gCwZxT jhhqBF"
          >
            <div
              class="sc-dAOnuy gpYqzl"
              title="Wallet Info"
            >
              <div
                class="sc-gjAXCV hBhImj"
              >
                <div
                  class="sc-dOkuiw cpJVOF"
                  title="Price in Local Currency"
                >
                  1 
                  XEC
                   = 
                  0.00003000
                   
                  USD
                </div>
                <div
                  class="sc-hZeNU dTTlAK"
                >
                  <div
                    class="sc-dXLFzO flexoP"
                  >
                    <label
                      class="sc-AqAhp jhgIub"
                    >
                      <input
                        checked=""
                        class="sc-cClmTo kBlGkd"
                        type="checkbox"
                      />
                      <div
                        class="sc-cZLAbK ehSOon"
                      >
                        <svg
                          fill="currentColor"
                          title="Visible"
                        />
                      </div>
                    </label>
                    <button
                      aria-label="Copy ecash:qr78y59zz80dm3cwuk388r097pupwdguau4d0kvns8"
                      class="sc-jbKcbu dkVUbc"
                    >
                      <svg
                        title="copy-paste"
                      />
                    </button>
                    <a
                      aria-label="Settings"
                      class="sc-eQGPmX loWKMf"
                      data-discover="true"
                      href="/configure"
                    >
                      <svg
                        title="Settings"
                      />
                    </a>
                  </div>
                  <select
                    class="sc-hMjcWo fTFPbo"
                    data-testid="wallet-select"
                    disabled=""
                    id="wallets"
                    name="wallets"
                  >
                    <option
                      class="sc-bLJvFH hmxMJi"
                      value="ecash:qr78y59zz80dm3cwuk388r097pupwdguau4d0kvns8"
                    >
                      Etokens Test
                    </option>
                  </select>
                </div>
              </div>
              <div
                class="sc-hgzKov iYccBj"
              >
                <div
                  class="sc-hCbubC ktxmdG"
                >
                  <div
                    aria-label="Toggle XEC and XECX balances"
                    class="sc-enfXDO eMvxwa"
                    data-tooltip-html="<div style=\"display:grid;grid-template-columns:max-content auto;column-gap:0.35em;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-variant-numeric:tabular-nums\"><span style=\"text-align:right\">975,111</span><span>XEC</span><span style=\"text-align:right\">0</span><span>XECX</span></div>"
                    data-tooltip-id="cashtab-tooltip"
                    data-tooltip-place="bottom"
                    role="button"
                    tabindex="0"
                  >
                    <div
                      class="sc-jgVwMx fqjTFn"
                    >
                      <svg />
                      eCash
                      <span
                        class="sc-kWHCRG gWeGoW"
                      >
                        XEC
                      </span>
                    </div>
                    <div
                      class="sc-SFOxd jrsUgQ"
                    >
                      <div
                        class="sc-AUpyg kkajLG"
                        title="Balance XEC"
                      >
                        975,111
                      </div>
                      <div
                        class="sc-ijnzTp fatGZH"
                        title="Balance XEC Fiat"
                      >
                        $
                        29.25
                         
                        USD
                      </div>
                    </div>
                    <div
                      class="sc-fUdGnz WKEhn"
                      title="Staked"
                    >
                      0%
                       
                      <a
                        class="sc-giOsra kxACoy"
                        data-discover="true"
                        href="/token/c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4"
                      >
                        staked
                      </a>
                    </div>
                  </div>
                  <a
                    class="sc-kMBllD hyotaV"
                    data-discover="true"
                    href="/token/0387947fd575db4fb19a3e322f635dec37fd192b5941625b66bc4b2c3008cbf0"
                    tokenlabel="USD"
                  >
                    <div
                      class="sc-jgVwMx fqjTFn"
                    >
                      <svg />
                      USD
                    </div>
                    <div
                      class="sc-AUpyg kkajLG"
                      title="Balance USD"
                    >
                      $0.0000
                    </div>
                  </a>
                </div>
              </div>
            </div>
            <div
              class="sc-gYtlsd iRXYtM"
            >
              <img
                alt="tabcash"
                class="sc-ekHBYt hlQogD"
                src="test-file-stub"
              />
              <div
                class="sc-uJMKN eDJSRK"
                title="Loading tokens"
              />
            </div>
          </div>
        </div>
        <div
          class="sc-iWadT bBHEFz"
        >
          <div
            class="sc-eTyWNx huTPsy"
          >
            <img
              alt="cashtab"
              class="sc-cLxPOX cpEwzk"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Send / Receive
            </span>
            <svg />
          </button>
          <button
            aria-label="Tokens"
            class="sc-cAJUJo DXTIt"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Agora"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Agora
            </span>
            <svg
              title="Meme Agora"
            />
          </button>
          <button
            aria-label="Tools"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Tools
            </span>
            <svg />
          </button>
          <button
            aria-label="Settings"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Settings
            </span>
            <svg />
          </button>
        </div>
      </div>
    </div>
  </div>
</body>
    at Object.getElementError (/work/node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/query-helpers.js:109:15
    at Object.getAllByTitle (/work/cashtab/src/components/Etokens/__tests__/Etokens.test.tsx:70:39)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)
====== CashTab Unit Tests: <Etokens /> Collections filter shows parent collection when user holds NFT but not collection token ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/Etokens.test.tsx:188:59)
    at runNextTicks (node:internal/process/task_queues:65:5)
    at listOnTimeout (node:internal/timers:549:9)
    at processTimers (node:internal/timers:523:7)

Each failure log is accessible here:
CashTab Unit Tests: <Agora /> We can see multiple offers, some we made, others we did not, and we can cancel an offer
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - ALP token send with empp_raw cashtab msg
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 - token send-to-many renders in token mode from URL params
CashTab Unit Tests: <Etokens /> Large token list is rendered and searchable
CashTab Unit Tests: <Etokens /> Collections filter shows parent collection when user holds NFT but not collection token

Failed tests logs:

====== CashTab Unit Tests: <Etokens /> Large token list is rendered and searchable ======
TestingLibraryElementError: Unable to find an element with the title: Token List Item.

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-kAzzGY bFOoJn"
      title="Loading..."
    >
      <div
        class="sc-cSHVUG kmQSTX"
        title="Loading"
      >
        <div />
        <div />
        <div />
        <div />
      </div>
    </div>
    <div
      class="sc-jbWsrJ dmgmcX"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-hqGPoI jLOaEj"
      >
        <div
          class="sc-imAxmJ gKMUad"
        >
          <div
            class="sc-gCwZxT jhhqBF"
          >
            <div
              class="sc-dAOnuy gpYqzl"
              title="Wallet Info"
            >
              <div
                class="sc-gjAXCV hBhImj"
              >
                <div
                  class="sc-dOkuiw cpJVOF"
                  title="Price in Local Currency"
                >
                  1 
                  XEC
                   = 
                  0.00003000
                   
                  USD
                </div>
                <div
                  class="sc-hZeNU dTTlAK"
                >
                  <div
                    class="sc-dXLFzO flexoP"
                  >
                    <label
                      class="sc-AqAhp jhgIub"
                    >
                      <input
                        checked=""
                        class="sc-cClmTo kBlGkd"
                        type="checkbox"
                      />
                      <div
                        class="sc-cZLAbK ehSOon"
                      >
                        <svg
                          fill="currentColor"
                          title="Visible"
                        />
                      </div>
                    </label>
                    <button
                      aria-label="Copy ecash:qr78y59zz80dm3cwuk388r097pupwdguau4d0kvns8"
                      class="sc-jbKcbu dkVUbc"
                    >
                      <svg
                        title="copy-paste"
                      />
                    </button>
                    <a
                      aria-label="Settings"
                      class="sc-eQGPmX loWKMf"
                      data-discover="true"
                      href="/configure"
                    >
                      <svg
                        title="Settings"
                      />
                    </a>
                  </div>
                  <select
                    class="sc-hMjcWo fTFPbo"
                    data-testid="wallet-select"
                    disabled=""
                    id="wallets"
                    name="wallets"
                  >
                    <option
                      class="sc-bLJvFH hmxMJi"
                      value="ecash:qr78y59zz80dm3cwuk388r097pupwdguau4d0kvns8"
                    >
                      Etokens Test
                    </option>
                  </select>
                </div>
              </div>
              <div
                class="sc-hgzKov iYccBj"
              >
                <div
                  class="sc-hCbubC ktxmdG"
                >
                  <div
                    aria-label="Toggle XEC and XECX balances"
                    class="sc-enfXDO eMvxwa"
                    data-tooltip-html="<div style=\"display:grid;grid-template-columns:max-content auto;column-gap:0.35em;font-family:ui-monospace,SFMono-Regular,Menlo,Monaco,Consolas,monospace;font-variant-numeric:tabular-nums\"><span style=\"text-align:right\">975,111</span><span>XEC</span><span style=\"text-align:right\">0</span><span>XECX</span></div>"
                    data-tooltip-id="cashtab-tooltip"
                    data-tooltip-place="bottom"
                    role="button"
                    tabindex="0"
                  >
                    <div
                      class="sc-jgVwMx fqjTFn"
                    >
                      <svg />
                      eCash
                      <span
                        class="sc-kWHCRG gWeGoW"
                      >
                        XEC
                      </span>
                    </div>
                    <div
                      class="sc-SFOxd jrsUgQ"
                    >
                      <div
                        class="sc-AUpyg kkajLG"
                        title="Balance XEC"
                      >
                        975,111
                      </div>
                      <div
                        class="sc-ijnzTp fatGZH"
                        title="Balance XEC Fiat"
                      >
                        $
                        29.25
                         
                        USD
                      </div>
                    </div>
                    <div
                      class="sc-fUdGnz WKEhn"
                      title="Staked"
                    >
                      0%
                       
                      <a
                        class="sc-giOsra kxACoy"
                        data-discover="true"
                        href="/token/c67bf5c2b6d91cfb46a5c1772582eff80d88686887be10aa63b0945479cf4ed4"
                      >
                        staked
                      </a>
                    </div>
                  </div>
                  <a
                    class="sc-kMBllD hyotaV"
                    data-discover="true"
                    href="/token/0387947fd575db4fb19a3e322f635dec37fd192b5941625b66bc4b2c3008cbf0"
                    tokenlabel="USD"
                  >
                    <div
                      class="sc-jgVwMx fqjTFn"
                    >
                      <svg />
                      USD
                    </div>
                    <div
                      class="sc-AUpyg kkajLG"
                      title="Balance USD"
                    >
                      $0.0000
                    </div>
                  </a>
                </div>
              </div>
            </div>
            <div
              class="sc-gYtlsd iRXYtM"
            >
              <img
                alt="tabcash"
                class="sc-ekHBYt hlQogD"
                src="test-file-stub"
              />
              <div
                class="sc-uJMKN eDJSRK"
                title="Loading tokens"
              />
            </div>
          </div>
        </div>
        <div
          class="sc-iWadT bBHEFz"
        >
          <div
            class="sc-eTyWNx huTPsy"
          >
            <img
              alt="cashtab"
              class="sc-cLxPOX cpEwzk"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Send / Receive
            </span>
            <svg />
          </button>
          <button
            aria-label="Tokens"
            class="sc-cAJUJo DXTIt"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Agora"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Agora
            </span>
            <svg
              title="Meme Agora"
            />
          </button>
          <button
            aria-label="Tools"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Tools
            </span>
            <svg />
          </button>
          <button
            aria-label="Settings"
            class="sc-cAJUJo biRmgr"
          >
            <span>
              Settings
            </span>
            <svg />
          </button>
        </div>
      </div>
    </div>
  </div>
</body>
    at Object.getElementError (/work/node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/node_modules/.pnpm/@testing-library+dom@10.4.1/node_modules/@testing-library/dom/dist/query-helpers.js:109:15
    at Object.getAllByTitle (/work/cashtab/src/components/Etokens/__tests__/Etokens.test.tsx:70:39)
====== CashTab Unit Tests: <Etokens /> Collections filter shows parent collection when user holds NFT but not collection token ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/Etokens.test.tsx:188:59)

Each failure log is accessible here:
CashTab Unit Tests: <Etokens /> Large token list is rendered and searchable
CashTab Unit Tests: <Etokens /> Collections filter shows parent collection when user holds NFT but not collection token

Stop blanking the Etokens list on context loading during cache hydration. Await Cashtab Loading and Loading tokens in Etokens tests instead of racing the first paint.

bytesofman edited the test plan for this revision. (Show Details)
Fabien requested changes to this revision.Tue, Jul 21, 13:22

This diff does 2 things, a rounding change to the balance display and the card tapping feature.
The latter one seems good (I need to check how it looks from the preview which has an unrelated issue) but the first one seems wrong to me and there is no rationale about it. Why would your wallet not show the exact balance ?

cashtab/src/components/Agora/__tests__/index.test.tsx
913 ↗(On Diff #60437)

Is that intentional ? I don't think it's correct, the balance should show the exact amount

cashtab/src/components/Etokens/Etokens.tsx
125 ↗(On Diff #60437)

OK but unrelated to this diff

379 ↗(On Diff #60437)

can you explain this change ?

This revision now requires changes to proceed.Tue, Jul 21, 13:22
bytesofman added inline comments.
cashtab/src/components/Agora/__tests__/index.test.tsx
913 ↗(On Diff #60437)

can back it out. it was about making sure there was enough room to show the value. for larger balances ... imo 123,456,111 is better than 123,456,111.23 -- but that is debatable and not really part of this change. will back it out.

cashtab/src/components/Etokens/Etokens.tsx
125 ↗(On Diff #60437)

see comment below

379 ↗(On Diff #60437)

started seeing a test fail here seemingly unrelated to the diff, but on inspection, most likely a race condition related to the extra time taken to support more values with the hook used to animate flip-up numbers

bytesofman added inline comments.
cashtab/src/components/Etokens/Etokens.tsx
125 ↗(On Diff #60437)

split this out into D20362

Rebase on master (Etokens changes landed in D20362). Drop >10k XEC/XECX decimal rounding so balances stay exact.

Build Bitcoin ABC Diffs / Diff Testing (ai-review) passed.
CodeRabbit Review

Diff : committed changes only
Compare : HEAD → master
Directory : work
────────────────────────────────────────

(\(\
(• .•) Your feature is behind a flag. Your bug is already in production.

────────────────────────────────────────────────────────────────────────

major [Functional Correctness]
→ ]8;;vscode://file//work/cashtab/src/components/Header/index.tsx:220cashtab/src/components/Header/index.tsx:220-228]8;;

Enter on the "staked" link toggles the breakdown instead of navigating.

onClick on StakedLink stops propagation, so mouse clicks navigate to
XECX without toggling. But keydown is not stopped: when the link is
focused and the user presses Enter, the event bubbles to the panel's
onKeyDown (Lines 165-170), which calls e.preventDefault() and
onToggleBreakdown(). That cancels the link's default activation, so
keyboard users toggle the breakdown rather than navigating to XECX.






🐛 Proposed fix: stop keyboard propagation on the link

                 <StakedLink
                     to={stakedHref}
                     onClick={(e: React.MouseEvent) => {
                         // Navigate to XECX; do not toggle breakdown.
                         e.stopPropagation();
                     }}
+                    onKeyDown={(e: React.KeyboardEvent) => {
+                        // Let the link handle Enter/Space; don't toggle the card.
+                        if (e.key === 'Enter' || e.key === ' ') {
+                            e.stopPropagation();
+                        }
+                    }}
                 >
                     staked
                 </StakedLink>

────────────────────────────────────────
Review complete
1 finding ✔

Major 1

5 files reviewed:

  • cashtab/src/components/Agora/__tests__/index.test.tsx
  • cashtab/src/components/Header/__tests__/Header.test.tsx
  • cashtab/src/components/Header/index.tsx
  • cashtab/src/components/Header/styled.ts
  • cashtab/src/components/Send/__tests__/SendByUrlParams.test.js

────────────────────────────────────────

Print all AI prompts: coderabbit review --show-prompts

Stop Enter/Space on the staked link from bubbling to the eCash card keydown handler so keyboard users navigate to XECX instead of toggling the breakdown.

Build Bitcoin ABC Diffs / Diff Testing (ai-review) passed.
CodeRabbit Review

Diff : committed changes only
Compare : HEAD → master
Directory : work
────────────────────────────────────────

(\(\
(• .•) Your cache invalidation strategy is 'vibes and hope'.

────────────────────────────────────────────────────────────────────────

major [Functional Correctness]
→ ]8;;vscode://file//work/cashtab/src/components/Header/index.tsx:159cashtab/src/components/Header/index.tsx:159-170]8;;

Keep StakedLink outside the card’s button semantics.

A link nested inside role="button" creates conflicting interactive
semantics and may make the XECX navigation inaccessible to assistive
technology. Use a sibling native button for the toggle region, add
aria-expanded={showBreakdown}, and keep StakedLink outside it.




Also applies to: 218-234

────────────────────────────────────────────────────────────────────────

minor [Functional Correctness]
→ ]8;;vscode://file//work/cashtab/src/components/Header/index.tsx:349cashtab/src/components/Header/index.tsx:349-355]8;;

Gate Firma fiat rendering on firmaPrice.

The current gate uses XEC’s fiatPrice, so a valid Firma fiat amount
disappears when only the XEC quote is unavailable.


Proposed fix

-                renderFiatValues={renderFiatValues && showFirmaFiat}
+                renderFiatValues={showFirmaFiat && firmaPrice !== null}

────────────────────────────────────────
Review complete
2 findings ✔

Major 1
Minor 1

5 files reviewed:

  • cashtab/src/components/Agora/__tests__/index.test.tsx
  • cashtab/src/components/Header/__tests__/Header.test.tsx
  • cashtab/src/components/Header/index.tsx
  • cashtab/src/components/Header/styled.ts
  • cashtab/src/components/Send/__tests__/SendByUrlParams.test.js

────────────────────────────────────────

Print all AI prompts: coderabbit review --show-prompts

imo the most recent coderabbit review should not be implemented. the firma price isn't the xec price in USD it is related to firma redeems. the accessibility thing is an optimization not a major problem.

Can you please rebase after D20360 has landed?

Build Bitcoin ABC Diffs / Diff Testing (ai-review) passed.
CodeRabbit Review

Diff : committed changes only
Compare : HEAD → master
Directory : work
────────────────────────────────────────

(\(\
(• .•) Pulling the bugs out of the hat.

────────────────────────────────────────────────────────────────────────

minor [Functional Correctness]
→ ]8;;vscode://file//work/cashtab/src/components/Header/__tests__/Header.test.tsx:137cashtab/src/components/Header/__tests__/Header.test.tsx:137-183]8;;

Assert that the standalone XECX card remains absent.

These assertions pass if the combined eCash card regresses into a combined
card plus a dedicated Balance XECX card. Retain `queryByTitle('Balance
XECX')` absence checks in the expanded and collapsed states.






Proposed test coverage

 expect(screen.getByTitle('Liquid and staked')).toHaveTextContent(
     /9,513\.12\s*XEC\s*9,513\.12\s*XECX/,
 );
+expect(screen.queryByTitle('Balance XECX')).not.toBeInTheDocument();

 // Tap again → restore combined total + fiat
 fireEvent.click(ecashCard);
 expect(screen.getByTitle('Balance XEC')).toHaveTextContent('19,026.24');
+expect(screen.queryByTitle('Balance XECX')).not.toBeInTheDocument();

Also applies to: 359-381

────────────────────────────────────────
Review complete
1 finding ✔

Minor 1

5 files reviewed:

  • cashtab/src/components/Agora/__tests__/index.test.tsx
  • cashtab/src/components/Header/__tests__/Header.test.tsx
  • cashtab/src/components/Header/index.tsx
  • cashtab/src/components/Header/styled.ts
  • cashtab/src/components/Send/__tests__/SendByUrlParams.test.js

────────────────────────────────────────

Print all AI prompts: coderabbit review --show-prompts

This revision is now accepted and ready to land.Wed, Jul 22, 12:05