Page MenuHomePhabricator

[cashtab] Header UI overhaul
Needs ReviewPublic

Authored by johnkuney on Thu, May 8, 16:30.

Details

Reviewers
None
Group Reviewers
Restricted Project
Summary

Proposed ui changes and code consolidation for the cashtab header.

  • consolidate header code into one component
  • new ui cards for xec, xecx, and firma balances with individual fiat balances
  • xecx and firma info in place of 0 balances
  • cleaned up wallet select, copy address and hide balances
  • update tests to work with new header

new ui

Screenshot 2025-05-08 at 11.39.59 PM.png (951×1 px, 294 KB)

old ui

Screenshot 2025-05-08 at 11.40.27 PM.png (957×1 px, 124 KB)

Test Plan

preview the app and check the header is working right

Diff Detail

Repository
rABC Bitcoin ABC
Branch
cashtab-header
Lint
Lint Errors
SeverityLocationCodeMessage
Errorcashtab/src/components/Header/__tests__/Header.test.js:297ESLINTheader/header
Errorcashtab/src/components/Header/styled.ts:271ESLINTeol-last
Unit
No Test Coverage
Build Status
Buildable 33246
Build 65974: Build Diffcashtab-tests
Build 65973: arc lint + arc unit

Event Timeline

Failed tests logs:

====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:83:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. Invalid bip21 string is ignored. ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:151:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and value present as undefined ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:214:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and no value key present ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:277:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params are not parsed as bip21 even if the bip21 param appears in the string ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:455:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount and op_return_raw is parsed as expected ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:522:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - an invalid bip21 param shows validation errors but cannot be changed ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:631:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount, op_return_raw, and additional output with amount is parsed as expected ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:768:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 token send ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:884:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/CreateToken.test.js:100:53)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/App/fixtures/__tests__/CashtabTestWrapper.test.js:93:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Wallet with XECX sees XECX balance and XECX balance included in fiat balance ======
Error: Unable to find an element with the text: XECX. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-chAAoq jkkmQa"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-dTLGrV iMTVPI"
      >
        <div
          class="sc-ivVeuv imkPeP"
        >
          <div
            class="sc-jkCMRl gBTeFC"
            title="Wallet Info"
          >
            <div
              class="sc-crNyjn gqmBAK"
            >
              <img
                alt="cashtab"
                src="test-file-stub"
              />
              <div
                class="sc-eitiEO uCLiu"
                title="Price in Local Currency mobile"
              >
                1 
                XEC
                 = 
                0.00003000
                 
                USD
              </div>
            </div>
            <div
              class="sc-cpHetk bqInKj"
            >
              <div
                class="sc-nrwXf iouDbQ"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                0.00003000
                 
                USD
              </div>
              <div
                class="sc-bhlBdH beSwKX"
              >
                <label
                  class="sc-fATqzn cnBMmz"
                >
                  <input
                    checked=""
                    class="sc-jbWsrJ fSnvyw"
                    type="checkbox"
                  />
                  <div
                    class="sc-hqGPoI ghvDYG"
                  >
                    <img
                      alt="toggle icon"
                      src="test-file-stub"
                    />
                  </div>
                </label>
                <button
                  aria-label="Copy ecash:qqa9lv3kjd8vq7952p7rq0f6lkpqvlu0cydvxtd70g"
                  class="sc-jbKcbu gcmUUo"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <select
                  class="sc-AnqlK jgCzha"
                  data-testid="wallet-select"
                  id="wallets"
                  name="wallets"
                >
                  <option
                    class="sc-keFjpB mCdBx"
                    value="Transaction Fixtures"
                  >
                    Transaction Fixtures
                  </option>
                </select>
              </div>
            </div>
            <div
              class="sc-kVrTmx keOBpK"
            >
              <div
                class="sc-ekkqgF gPoRVh"
              >
                <img
                  alt="eCash"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr drxoNI"
                >
                  eCash
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XEC"
                >
                  9,513.12
                   
                  XEC
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XEC Fiat"
                >
                  $
                  0.29
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hsWQid"
              >
                <img
                  alt="eCash Staking"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr eFsfCF"
                >
                  Staking
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XECX"
                >
                  100,000,000.00
                   
                  XECX
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XECX Fiat"
                >
                  $
                  3,000.00
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hlnDNb"
              >
                <img
                  alt="Savings"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr kTbzgw"
                >
                  Savings
                </div>
                <...
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/App/__tests__/App.test.js:650:29)
====== CashTab Unit Tests: <App /> A new user can import a mnemonic of a wallet with a balance ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:737:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:787:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with pre-2.1.0 valid wallets in savedWallets has them all migrated to new storage keys and new shape ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:825:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Cashtab version >= 1.6.0 and < 2.1.0: A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:941:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating (version < 2.9.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:1045:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating (2.9.0 <= version < 2.55.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:1121:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <Token /> available actions rendered We can redeem 1 Firma for $1 of XEC using a workflow unique to Firma ======
TestingLibraryElementError: Unable to find an element with the alt text: icon for 0387947fd575db4fb19a3e322f635dec37fd192b5941625b66bc4b2c3008cbf0

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-kAzzGY bFOoJn"
      title="Loading..."
    >
      <div
        class="sc-cSHVUG kakYiA"
        title="Loading"
      >
        <div />
        <div />
        <div />
        <div />
      </div>
    </div>
    <div
      class="sc-chAAoq jkkmQa"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-dTLGrV iMTVPI"
      >
        <div
          class="sc-ivVeuv imkPeP"
        >
          <div
            class="sc-jkCMRl gBTeFC"
            title="Wallet Info"
          >
            <div
              class="sc-crNyjn gqmBAK"
            >
              <img
                alt="cashtab"
                src="test-file-stub"
              />
              <div
                class="sc-eitiEO uCLiu"
                title="Price in Local Currency mobile"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
            </div>
            <div
              class="sc-cpHetk bqInKj"
            >
              <div
                class="sc-nrwXf iouDbQ"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
              <div
                class="sc-bhlBdH beSwKX"
              >
                <label
                  class="sc-hPeUyl cLIein"
                >
                  <input
                    checked=""
                    class="sc-esoVGF kdvVKS"
                    type="checkbox"
                  />
                  <div
                    class="sc-cAJUJo gJkONv"
                  >
                    <img
                      alt="toggle icon"
                      src="test-file-stub"
                    />
                  </div>
                </label>
                <button
                  aria-label="Copy ecash:qqq9f9z3uhpzkxrgdjkd7dxuuey7tmpmugpmnw0kue"
                  class="sc-jbKcbu gcmUUo"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <select
                  class="sc-AnqlK jgCzha"
                  data-testid="wallet-select"
                  disabled=""
                  id="wallets"
                  name="wallets"
                >
                  <option
                    class="sc-keFjpB mCdBx"
                    value="Token Test"
                  >
                    Token Test
                  </option>
                </select>
              </div>
            </div>
            <div
              class="sc-kVrTmx keOBpK"
            >
              <div
                class="sc-ekkqgF gPoRVh"
              >
                <img
                  alt="eCash"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr drxoNI"
                >
                  eCash
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XEC"
                >
                  9,970.81
                   
                  XEC
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XEC Fiat"
                >
                  $
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hsWQid"
              >
                <img
                  alt="eCash Staking"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr eFsfCF"
                >
                  Staking
                </div>
                <span
                  title="Get XECX"
                >
                  Earn eCash passively by staking with XECX! Daily staking rewards paid directly to your wallet.
                   
                  <a
                    href="https://stakedxec.com"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
              <div
                class="sc-ekkqgF hlnDNb"
              >
                <img
                  alt="Savings"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr kTbzgw"
                >
                  Savings
                </div>
                <span
                  title="Get FIRMA"
                >
                  Earn USD yield with the Firma stable coin. Daily native yield paid directly to your wallet.
                   
                  <a
                    href="https://firma.cash"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
            </div>
          </div>
          <div
            class="sc-dBaXSw eahevx"
          >
            <div
              class="sc-kxynE cPkfiL"
            >
              <div
                class="sc-cooIXK jIUhVw"
                title="Token Info"
              >
                <div
                  class="sc-kAzzGY bFOoJn"
                  title="Loading..."
                >
                  <div
                    class="sc-cSHVUG kakYiA"
                    title="Loading"
                  >
                    <div />
                    <div />
                    <div />
                    <div />
                  </div>
                </div>
                <div
                  class="sc-ktHwxA fAHhjp"
                >
                  You do not hold this token.
                </div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="sc-cCbXAZ fWfLQK"
        >
          <div
            class="sc-hizQCF iOBvKI"
          >
            <img
              alt="cashtab"
              class="sc-dRCTWM jaayJi"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-gleUXh jOucit"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-gleUXh jOucit"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-gleUXh jOucit"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-gleUXh jOucit"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-fHSTwm fmqsjL nav-menu-container"
            title="Show Other Screens"
          >
            <span
              class="sc-hdPSEv kpKbSe"
            />
            <div
              class="sc-cmIlrE kXQSWU"
              title="Other Screens"
            >
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Settings
                </p>
                <svg
                  title="settings"
                />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByAltText (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:2300:20)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <Token /> available actions rendered We show expected error if we are unable to get FIRMA bid price from API ======
TestingLibraryElementError: Unable to find an element with the alt text: icon for 0387947fd575db4fb19a3e322f635dec37fd192b5941625b66bc4b2c3008cbf0

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-kAzzGY bFOoJn"
      title="Loading..."
    >
      <div
        class="sc-cSHVUG kakYiA"
        title="Loading"
      >
        <div />
        <div />
        <div />
        <div />
      </div>
    </div>
    <div
      class="sc-chAAoq jkkmQa"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-dTLGrV iMTVPI"
      >
        <div
          class="sc-ivVeuv imkPeP"
        >
          <div
            class="sc-jkCMRl gBTeFC"
            title="Wallet Info"
          >
            <div
              class="sc-crNyjn gqmBAK"
            >
              <img
                alt="cashtab"
                src="test-file-stub"
              />
              <div
                class="sc-eitiEO uCLiu"
                title="Price in Local Currency mobile"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
            </div>
            <div
              class="sc-cpHetk bqInKj"
            >
              <div
                class="sc-nrwXf iouDbQ"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
              <div
                class="sc-bhlBdH beSwKX"
              >
                <label
                  class="sc-cmUJln cMtCnz"
                >
                  <input
                    checked=""
                    class="sc-gYtlsd byfOZy"
                    type="checkbox"
                  />
                  <div
                    class="sc-kDgGX dwxdan"
                  >
                    <img
                      alt="toggle icon"
                      src="test-file-stub"
                    />
                  </div>
                </label>
                <button
                  aria-label="Copy ecash:qqq9f9z3uhpzkxrgdjkd7dxuuey7tmpmugpmnw0kue"
                  class="sc-jbKcbu gcmUUo"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <select
                  class="sc-AnqlK jgCzha"
                  data-testid="wallet-select"
                  disabled=""
                  id="wallets"
                  name="wallets"
                >
                  <option
                    class="sc-keFjpB mCdBx"
                    value="Token Test"
                  >
                    Token Test
                  </option>
                </select>
              </div>
            </div>
            <div
              class="sc-kVrTmx keOBpK"
            >
              <div
                class="sc-ekkqgF gPoRVh"
              >
                <img
                  alt="eCash"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr drxoNI"
                >
                  eCash
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XEC"
                >
                  9,970.81
                   
                  XEC
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XEC Fiat"
                >
                  $
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hsWQid"
              >
                <img
                  alt="eCash Staking"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr eFsfCF"
                >
                  Staking
                </div>
                <span
                  title="Get XECX"
                >
                  Earn eCash passively by staking with XECX! Daily staking rewards paid directly to your wallet.
                   
                  <a
                    href="https://stakedxec.com"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
              <div
                class="sc-ekkqgF hlnDNb"
              >
                <img
                  alt="Savings"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr kTbzgw"
                >
                  Savings
                </div>
                <span
                  title="Get FIRMA"
                >
                  Earn USD yield with the Firma stable coin. Daily native yield paid directly to your wallet.
                   
                  <a
                    href="https://firma.cash"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
            </div>
          </div>
          <div
            class="sc-dBaXSw eahevx"
          >
            <div
              class="sc-kxynE cPkfiL"
            >
              <div
                class="sc-cooIXK jIUhVw"
                title="Token Info"
              >
                <div
                  class="sc-kAzzGY bFOoJn"
                  title="Loading..."
                >
                  <div
                    class="sc-cSHVUG kakYiA"
                    title="Loading"
                  >
                    <div />
                    <div />
                    <div />
                    <div />
                  </div>
                </div>
                <div
                  class="sc-ktHwxA fAHhjp"
                >
                  You do not hold this token.
                </div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="sc-cCbXAZ fWfLQK"
        >
          <div
            class="sc-hizQCF iOBvKI"
          >
            <img
              alt="cashtab"
              class="sc-dRCTWM jaayJi"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-gleUXh jOucit"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-gleUXh jOucit"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-gleUXh jOucit"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-gleUXh jOucit"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-fHSTwm fmqsjL nav-menu-container"
            title="Show Other Screens"
          >
            <span
              class="sc-hdPSEv kpKbSe"
            />
            <div
              class="sc-cmIlrE kXQSWU"
              title="Other Screens"
            >
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Settings
                </p>
                <svg
                  title="settings"
                />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByAltText (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:2428:20)
====== CashTab Unit Tests: <Token /> available actions rendered The FIRMA OrderBook loads with price in USD ======
Error: expect(received).toHaveLength(expected)

Expected length: 4
Received length: 1
Received array:  [<span title="Get FIRMA">Earn USD yield with the Firma stable coin. Daily native yield paid directly to your wallet. <a href="https://firma.cash" rel="noopener noreferrer" target="_blank">Learn more</a></span>]
    at Object.toHaveLength (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:2508:67)

Each failure log is accessible here:
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid.
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. Invalid bip21 string is ignored.
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and value present as undefined
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and no value key present
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params are not parsed as bip21 even if the bip21 param appears in the string
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount and op_return_raw is parsed as expected
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - an invalid bip21 param shows validation errors but cannot be changed
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount, op_return_raw, and additional output with amount is parsed as expected
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 token send
CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm
CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component
CashTab Unit Tests: <App /> Wallet with XECX sees XECX balance and XECX balance included in fiat balance
CashTab Unit Tests: <App /> A new user can import a mnemonic of a wallet with a balance
CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with pre-2.1.0 valid wallets in savedWallets has them all migrated to new storage keys and new shape
CashTab Unit Tests: <App /> Cashtab version >= 1.6.0 and < 2.1.0: A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating (version < 2.9.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating (2.9.0 <= version < 2.55.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <Token /> available actions rendered We can redeem 1 Firma for $1 of XEC using a workflow unique to Firma
CashTab Unit Tests: <Token /> available actions rendered We show expected error if we are unable to get FIRMA bid price from API
CashTab Unit Tests: <Token /> available actions rendered The FIRMA OrderBook loads with price in USD

Failed tests logs:

====== CashTab Unit Tests: <Home /> Renders the loading component while loading, then the Home screen ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Home/__tests__/Home.test.js:79:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:83:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. Invalid bip21 string is ignored. ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:151:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and value present as undefined ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:214:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and no value key present ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:277:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params are not parsed as bip21 even if the bip21 param appears in the string ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:455:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount and op_return_raw is parsed as expected ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:522:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - an invalid bip21 param shows validation errors but cannot be changed ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:631:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount, op_return_raw, and additional output with amount is parsed as expected ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:768:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 token send ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Send/__tests__/SendByUrlParams.test.js:884:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <Header /> renders correctly with default props and visible balance ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  1 XEC = 0.0000 USD
Received:
  1 XEC = 0.00003000 USD
    at Object.toHaveTextContent (/work/cashtab/src/components/Header/__tests__/Header.test.js:41:62)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <Header /> formats numbers based on userLocale ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  10,000,000,00 XEC
Received:
  10 000 000,00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/Header/__tests__/Header.test.js:160:50)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <Header /> does not render fiat values if fiatPrice is null ======
Error: expect(element).not.toBeInTheDocument()

expected document not to contain element, found <div class="sc-jAaTju bVBZDJ" title="Balance XEC Fiat">$ USD</div> instead
    at Object.toBeInTheDocument (/work/cashtab/src/components/Header/__tests__/Header.test.js:188:61)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <Header /> does not render fiat price if fiatPrice is null ======
Error: expect(element).not.toBeInTheDocument()

expected document not to contain element, found <div class="sc-jAaTju bVBZDJ" title="Balance XEC Fiat">$ USD</div> instead
    at Object.toBeInTheDocument (/work/cashtab/src/components/Header/__tests__/Header.test.js:288:61)
    at Promise.then.completed (/work/cashtab/node_modules/jest-circus/build/utils.js:298:28)
    at new Promise (<anonymous>)
    at callAsyncCircusFn (/work/cashtab/node_modules/jest-circus/build/utils.js:231:10)
    at _callCircusTest (/work/cashtab/node_modules/jest-circus/build/run.js:316:40)
    at processTicksAndRejections (node:internal/process/task_queues:95:5)
    at _runTest (/work/cashtab/node_modules/jest-circus/build/run.js:252:3)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:126:9)
    at _runTestsForDescribeBlock (/work/cashtab/node_modules/jest-circus/build/run.js:121:9)
    at run (/work/cashtab/node_modules/jest-circus/build/run.js:71:3)
    at runAndTransformResultsToJestFormat (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapterInit.js:122:21)
    at jestAdapter (/work/cashtab/node_modules/jest-circus/build/legacy-code-todo-rewrite/jestAdapter.js:79:19)
    at runTestInternal (/work/cashtab/node_modules/jest-runner/build/runTest.js:367:16)
    at runTest (/work/cashtab/node_modules/jest-runner/build/runTest.js:444:34)
    at Object.worker (/work/cashtab/node_modules/jest-runner/build/testWorker.js:106:12)
====== CashTab Unit Tests: <Nfts /> If we switch wallets, listings that were previously organized as "My Listing" are instead organized as for sale ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Nfts/__tests__/index.test.js:240:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/CreateToken.test.js:100:53)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component ======
Error: expect(element).toBeInTheDocument()

element could not be found in the document
    at Object.toBeInTheDocument (/work/cashtab/src/components/App/fixtures/__tests__/CashtabTestWrapper.test.js:93:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Wallet with XECX sees XECX balance and XECX balance included in fiat balance ======
Error: Unable to find an element with the text: XECX. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-chAAoq jkkmQa"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-dTLGrV iMTVPI"
      >
        <div
          class="sc-ivVeuv imkPeP"
        >
          <div
            class="sc-jkCMRl gBTeFC"
            title="Wallet Info"
          >
            <div
              class="sc-crNyjn gqmBAK"
            >
              <img
                alt="cashtab"
                src="test-file-stub"
              />
              <div
                class="sc-eitiEO uCLiu"
                title="Price in Local Currency mobile"
              >
                1 
                XEC
                 = 
                0.00003000
                 
                USD
              </div>
            </div>
            <div
              class="sc-cpHetk bqInKj"
            >
              <div
                class="sc-nrwXf iouDbQ"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                0.00003000
                 
                USD
              </div>
              <div
                class="sc-bhlBdH beSwKX"
              >
                <label
                  class="sc-dTsoBL gLaUyB"
                >
                  <input
                    checked=""
                    class="sc-btewqU hwGqVr"
                    type="checkbox"
                  />
                  <div
                    class="sc-imapFV ieITnS"
                  >
                    <img
                      alt="toggle icon"
                      src="test-file-stub"
                    />
                  </div>
                </label>
                <button
                  aria-label="Copy ecash:qqa9lv3kjd8vq7952p7rq0f6lkpqvlu0cydvxtd70g"
                  class="sc-jbKcbu gcmUUo"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <select
                  class="sc-AnqlK jgCzha"
                  data-testid="wallet-select"
                  id="wallets"
                  name="wallets"
                >
                  <option
                    class="sc-keFjpB mCdBx"
                    value="Transaction Fixtures"
                  >
                    Transaction Fixtures
                  </option>
                </select>
              </div>
            </div>
            <div
              class="sc-kVrTmx keOBpK"
            >
              <div
                class="sc-ekkqgF gPoRVh"
              >
                <img
                  alt="eCash"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr drxoNI"
                >
                  eCash
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XEC"
                >
                  9,513.12
                   
                  XEC
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XEC Fiat"
                >
                  $
                  0.29
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hsWQid"
              >
                <img
                  alt="eCash Staking"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr eFsfCF"
                >
                  Staking
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XECX"
                >
                  100,000,000.00
                   
                  XECX
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XECX Fiat"
                >
                  $
                  3,000.00
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hlnDNb"
              >
                <img
                  alt="Savings"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr kTbzgw"
                >
                  Savings
                </div>
                <...
    at waitForWrapper (/work/cashtab/node_modules/@testing-library/dom/dist/wait-for.js:163:27)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:86:33
    at Object.findByText (/work/cashtab/src/components/App/__tests__/App.test.js:650:29)
====== CashTab Unit Tests: <App /> A new user can import a mnemonic of a wallet with a balance ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:737:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:787:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with pre-2.1.0 valid wallets in savedWallets has them all migrated to new storage keys and new shape ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:825:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Cashtab version >= 1.6.0 and < 2.1.0: A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:941:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating (version < 2.9.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:1045:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <App /> Migrating (2.9.0 <= version < 2.55.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup ======
Error: expect(element).toHaveTextContent()

Expected element to have text content:
  9,513.12 XEC
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:1121:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <Token /> available actions rendered We can redeem 1 Firma for $1 of XEC using a workflow unique to Firma ======
TestingLibraryElementError: Unable to find an element with the alt text: icon for 0387947fd575db4fb19a3e322f635dec37fd192b5941625b66bc4b2c3008cbf0

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-kAzzGY bFOoJn"
      title="Loading..."
    >
      <div
        class="sc-cSHVUG kakYiA"
        title="Loading"
      >
        <div />
        <div />
        <div />
        <div />
      </div>
    </div>
    <div
      class="sc-chAAoq jkkmQa"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-dTLGrV iMTVPI"
      >
        <div
          class="sc-ivVeuv imkPeP"
        >
          <div
            class="sc-jkCMRl gBTeFC"
            title="Wallet Info"
          >
            <div
              class="sc-crNyjn gqmBAK"
            >
              <img
                alt="cashtab"
                src="test-file-stub"
              />
              <div
                class="sc-eitiEO uCLiu"
                title="Price in Local Currency mobile"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
            </div>
            <div
              class="sc-cpHetk bqInKj"
            >
              <div
                class="sc-nrwXf iouDbQ"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
              <div
                class="sc-bhlBdH beSwKX"
              >
                <label
                  class="sc-hPeUyl cLIein"
                >
                  <input
                    checked=""
                    class="sc-esoVGF kdvVKS"
                    type="checkbox"
                  />
                  <div
                    class="sc-cAJUJo gJkONv"
                  >
                    <img
                      alt="toggle icon"
                      src="test-file-stub"
                    />
                  </div>
                </label>
                <button
                  aria-label="Copy ecash:qqq9f9z3uhpzkxrgdjkd7dxuuey7tmpmugpmnw0kue"
                  class="sc-jbKcbu gcmUUo"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <select
                  class="sc-AnqlK jgCzha"
                  data-testid="wallet-select"
                  disabled=""
                  id="wallets"
                  name="wallets"
                >
                  <option
                    class="sc-keFjpB mCdBx"
                    value="Token Test"
                  >
                    Token Test
                  </option>
                </select>
              </div>
            </div>
            <div
              class="sc-kVrTmx keOBpK"
            >
              <div
                class="sc-ekkqgF gPoRVh"
              >
                <img
                  alt="eCash"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr drxoNI"
                >
                  eCash
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XEC"
                >
                  9,970.81
                   
                  XEC
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XEC Fiat"
                >
                  $
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hsWQid"
              >
                <img
                  alt="eCash Staking"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr eFsfCF"
                >
                  Staking
                </div>
                <span
                  title="Get XECX"
                >
                  Earn eCash passively by staking with XECX! Daily staking rewards paid directly to your wallet.
                   
                  <a
                    href="https://stakedxec.com"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
              <div
                class="sc-ekkqgF hlnDNb"
              >
                <img
                  alt="Savings"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr kTbzgw"
                >
                  Savings
                </div>
                <span
                  title="Get FIRMA"
                >
                  Earn USD yield with the Firma stable coin. Daily native yield paid directly to your wallet.
                   
                  <a
                    href="https://firma.cash"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
            </div>
          </div>
          <div
            class="sc-dBaXSw eahevx"
          >
            <div
              class="sc-kxynE cPkfiL"
            >
              <div
                class="sc-cooIXK jIUhVw"
                title="Token Info"
              >
                <div
                  class="sc-kAzzGY bFOoJn"
                  title="Loading..."
                >
                  <div
                    class="sc-cSHVUG kakYiA"
                    title="Loading"
                  >
                    <div />
                    <div />
                    <div />
                    <div />
                  </div>
                </div>
                <div
                  class="sc-ktHwxA fAHhjp"
                >
                  You do not hold this token.
                </div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="sc-cCbXAZ fWfLQK"
        >
          <div
            class="sc-hizQCF iOBvKI"
          >
            <img
              alt="cashtab"
              class="sc-dRCTWM jaayJi"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-gleUXh jOucit"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-gleUXh jOucit"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-gleUXh jOucit"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-gleUXh jOucit"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-fHSTwm fmqsjL nav-menu-container"
            title="Show Other Screens"
          >
            <span
              class="sc-hdPSEv kpKbSe"
            />
            <div
              class="sc-cmIlrE kXQSWU"
              title="Other Screens"
            >
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Settings
                </p>
                <svg
                  title="settings"
                />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByAltText (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:2300:20)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)
====== CashTab Unit Tests: <Token /> available actions rendered We show expected error if we are unable to get FIRMA bid price from API ======
TestingLibraryElementError: Unable to find an element with the alt text: icon for 0387947fd575db4fb19a3e322f635dec37fd192b5941625b66bc4b2c3008cbf0

Ignored nodes: comments, script, style
<body>
  <div>
    <div
      class="sc-kAzzGY bFOoJn"
      title="Loading..."
    >
      <div
        class="sc-cSHVUG kakYiA"
        title="Loading"
      >
        <div />
        <div />
        <div />
        <div />
      </div>
    </div>
    <div
      class="sc-chAAoq jkkmQa"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-dTLGrV iMTVPI"
      >
        <div
          class="sc-ivVeuv imkPeP"
        >
          <div
            class="sc-jkCMRl gBTeFC"
            title="Wallet Info"
          >
            <div
              class="sc-crNyjn gqmBAK"
            >
              <img
                alt="cashtab"
                src="test-file-stub"
              />
              <div
                class="sc-eitiEO uCLiu"
                title="Price in Local Currency mobile"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
            </div>
            <div
              class="sc-cpHetk bqInKj"
            >
              <div
                class="sc-nrwXf iouDbQ"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                 
                USD
              </div>
              <div
                class="sc-bhlBdH beSwKX"
              >
                <label
                  class="sc-cmUJln cMtCnz"
                >
                  <input
                    checked=""
                    class="sc-gYtlsd byfOZy"
                    type="checkbox"
                  />
                  <div
                    class="sc-kDgGX dwxdan"
                  >
                    <img
                      alt="toggle icon"
                      src="test-file-stub"
                    />
                  </div>
                </label>
                <button
                  aria-label="Copy ecash:qqq9f9z3uhpzkxrgdjkd7dxuuey7tmpmugpmnw0kue"
                  class="sc-jbKcbu gcmUUo"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <select
                  class="sc-AnqlK jgCzha"
                  data-testid="wallet-select"
                  disabled=""
                  id="wallets"
                  name="wallets"
                >
                  <option
                    class="sc-keFjpB mCdBx"
                    value="Token Test"
                  >
                    Token Test
                  </option>
                </select>
              </div>
            </div>
            <div
              class="sc-kVrTmx keOBpK"
            >
              <div
                class="sc-ekkqgF gPoRVh"
              >
                <img
                  alt="eCash"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr drxoNI"
                >
                  eCash
                </div>
                <div
                  class="sc-jvEmr hLosaZ"
                  title="Balance XEC"
                >
                  9,970.81
                   
                  XEC
                </div>
                <div
                  class="sc-hycgNl cWNeRS"
                  title="Balance XEC Fiat"
                >
                  $
                   
                  USD
                </div>
              </div>
              <div
                class="sc-ekkqgF hsWQid"
              >
                <img
                  alt="eCash Staking"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr eFsfCF"
                >
                  Staking
                </div>
                <span
                  title="Get XECX"
                >
                  Earn eCash passively by staking with XECX! Daily staking rewards paid directly to your wallet.
                   
                  <a
                    href="https://stakedxec.com"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
              <div
                class="sc-ekkqgF hlnDNb"
              >
                <img
                  alt="Savings"
                  class="sc-iBmynh gVCGcd"
                  src="test-file-stub"
                />
                <div
                  class="sc-fKGOjr kTbzgw"
                >
                  Savings
                </div>
                <span
                  title="Get FIRMA"
                >
                  Earn USD yield with the Firma stable coin. Daily native yield paid directly to your wallet.
                   
                  <a
                    href="https://firma.cash"
                    rel="noopener noreferrer"
                    target="_blank"
                  >
                    Learn more
                  </a>
                </span>
              </div>
            </div>
          </div>
          <div
            class="sc-dBaXSw eahevx"
          >
            <div
              class="sc-kxynE cPkfiL"
            >
              <div
                class="sc-cooIXK jIUhVw"
                title="Token Info"
              >
                <div
                  class="sc-kAzzGY bFOoJn"
                  title="Loading..."
                >
                  <div
                    class="sc-cSHVUG kakYiA"
                    title="Loading"
                  >
                    <div />
                    <div />
                    <div />
                    <div />
                  </div>
                </div>
                <div
                  class="sc-ktHwxA fAHhjp"
                >
                  You do not hold this token.
                </div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="sc-cCbXAZ fWfLQK"
        >
          <div
            class="sc-hizQCF iOBvKI"
          >
            <img
              alt="cashtab"
              class="sc-dRCTWM jaayJi"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-gleUXh jOucit"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-gleUXh jOucit"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-gleUXh jOucit"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-gleUXh jOucit"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-fHSTwm fmqsjL nav-menu-container"
            title="Show Other Screens"
          >
            <span
              class="sc-hdPSEv kpKbSe"
            />
            <div
              class="sc-cmIlrE kXQSWU"
              title="Other Screens"
            >
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-doWzTn bTvygg"
              >
                <p>
                  Settings
                </p>
                <svg
                  title="settings"
                />
              </button>
            </div>
          </div>
        </div>
      </div>
    </div>
  </div>
</body>
    at Object.getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/config.js:37:19)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:76:38
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:52:17
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByAltText (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:2428:20)
====== CashTab Unit Tests: <Token /> available actions rendered The FIRMA OrderBook loads with price in USD ======
Error: expect(received).toHaveLength(expected)

Expected length: 4
Received length: 1
Received array:  [<span title="Get FIRMA">Earn USD yield with the Firma stable coin. Daily native yield paid directly to your wallet. <a href="https://firma.cash" rel="noopener noreferrer" target="_blank">Learn more</a></span>]
    at Object.toHaveLength (/work/cashtab/src/components/Etokens/__tests__/TokenActions.test.js:2508:67)

Each failure log is accessible here:
CashTab Unit Tests: <Home /> Renders the loading component while loading, then the Home screen
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid.
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address and value keys are set and valid. Invalid bip21 string is ignored.
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and value present as undefined
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params. Address field is populated + disabled while value field is empty + enabled if legacy url params have address defined and no value key present
CashTab Unit Tests: <SendXec /> rendered with params in URL Legacy params are not parsed as bip21 even if the bip21 param appears in the string
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount and op_return_raw is parsed as expected
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - an invalid bip21 param shows validation errors but cannot be changed
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 param with amount, op_return_raw, and additional output with amount is parsed as expected
CashTab Unit Tests: <SendXec /> rendered with params in URL bip21 param - valid bip21 token send
CashTab Unit Tests: <Header /> renders correctly with default props and visible balance
CashTab Unit Tests: <Header /> formats numbers based on userLocale
CashTab Unit Tests: <Header /> does not render fiat values if fiatPrice is null
CashTab Unit Tests: <Header /> does not render fiat price if fiatPrice is null
CashTab Unit Tests: <Nfts /> If we switch wallets, listings that were previously organized as "My Listing" are instead organized as for sale
CashTab Unit Tests: <CreateToken /> If wallet has insufficient XEC, renders component but does not render CreateTokenForm
CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component
CashTab Unit Tests: <App /> Wallet with XECX sees XECX balance and XECX balance included in fiat balance
CashTab Unit Tests: <App /> A new user can import a mnemonic of a wallet with a balance
CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating from wallet/savedWallet keys (version < 1.6.0): A user with pre-2.1.0 valid wallets in savedWallets has them all migrated to new storage keys and new shape
CashTab Unit Tests: <App /> Cashtab version >= 1.6.0 and < 2.1.0: A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating (version < 2.9.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <App /> Migrating (2.9.0 <= version < 2.55.0): A user with an invalid Cashtab wallet as the active wallet is migrated on startup
CashTab Unit Tests: <Token /> available actions rendered We can redeem 1 Firma for $1 of XEC using a workflow unique to Firma
CashTab Unit Tests: <Token /> available actions rendered We show expected error if we are unable to get FIRMA bid price from API
CashTab Unit Tests: <Token /> available actions rendered The FIRMA OrderBook loads with price in USD

bytesofman added inline comments.
cashtab/src/components/Header/__tests__/Header.test.js
42 ↗(On Diff #53907)

With a lot of these test failures, you just need to update these check values

e.g. here, we do not expect to see 1 XEC = 0.0000 USD, because you are passing in a fiatPrice of 0.00003

so -- patch

you may need to go through the tests one at a time. so, you could edit these tests and then check them with npm run debug Header -- which will run only the tests in this file -- incrementally patch the failures

extend this throughout

johnkuney published this revision for review.Fri, May 9, 04:41
johnkuney edited the summary of this revision. (Show Details)
johnkuney edited the summary of this revision. (Show Details)

In mobile mode, this new header now takes up 30% of the UI. I know it moves off the screen when scrolling but it reappears with navigating to a new component. I think tooltips like Staking and Savings should be able to be closed or minimized by the user? Or perhaps have an onHover icon?
Also the Learn more link on mobile screens are somewhat harder to click (maybe I just have fat fingers) - perhaps make the whole row a link?

image.png (933×665 px, 97 KB)