Page MenuHomePhabricator

[cashtab] Header UI overhaul
ClosedPublic

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

Details

Reviewers
bytesofman
Group Reviewers
Restricted Project
Commits
rABC3870a0ac7d0b: [cashtab] Header UI overhaul
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 Passed
Unit
No Test Coverage
Build Status
Buildable 33261
Build 66004: Build Diffcashtab-tests
Build 66003: arc lint + arc unit

Event Timeline

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

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)

For sure, fair points. I believe its not necessarily much taller than the current UI if you do have an XECX and Firma balance, but that shouldnt be the benchmark.
I can try for a more compact solution, and possibly look at allowing users to dismiss the info text

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)

I'm ok with the taller UI. we can iterate from here.

I don't think it's worth adding new settings options to show/hide this stuff just to make this improvement. But we could add that in the future if people really want it.

it's much better than the current UI, even with the height trade-off.

also a fair point. Rome wasnt built in a day haha

bytesofman requested changes to this revision.Fri, May 9, 21:15

image.png (809×1 px, 371 KB)

ok some specific recommendations

  • If user has no XECX or no FIRMA, show the tile with 0 balance
  • Make XECX ticker link to the XECX token page (so 0.00 XECX -> the XECX links to the token page, as it does now)
  • Make FIRMA ticker link to the FIRMA token page
  • could do in a later diff -- we should have info blurbs about what FIRMA/XECX are on their respective token pages.
This revision now requires changes to proceed.Fri, May 9, 21:15

It is better to remove the color bars on the left side of these small cards, as they may mislead people into thinking they are dismissible notifications, alerts, or clickable items.

Group 54.png (933×665 px, 151 KB)

  • Remove zero balance messaging and just show 0.00 balance
  • Add links to XECX and Firma token pages
  • Remove color border
  • add horizontal scroll on mobile to reduce height
  • simplify style props

nice imo this is much better than what we have currently. testing nit.

xecx and firma token pages should have some kind of info blurb about what the tokens are and how they work, but that can be handled in a separate diff

cashtab/src/components/Nfts/__tests__/index.test.js
240–242 ↗(On Diff #53965)

does expect(await screen.findByText('9,513.12 XEC')).toBeInTheDocument(); really fail here?

it's the same as using waitFor and is the preferred syntax

This revision is now accepted and ready to land.Tue, May 13, 12:33

Nice, for sure can get those in another diff.

As for the test edits, yes it will fail if I set it back to the previous syntax. There are probably some subtleties that are lost on me and maybe a way to make the preferred syntax work?
I'll dm you to discuss

Failed tests logs:

====== 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: <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
Received:
  0.00 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/App/__tests__/App.test.js:696:57)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)

Each failure log is accessible here:
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: <App /> A new user can import a mnemonic of a wallet with a balance

  • Remove cashtab/failed-tests.txt
  • using await screen.findByText with timeout instead of await waitFor()...
cashtab/src/components/App/__tests__/App.test.js
746 ↗(On Diff #53971)

should always use screen.findByTitle and never await waitFor if you are waiting for text content

use a timeout, e.g.

expect(
            await screen.findByText('9,513.12 XEC', {}, { timeout: 10000 }),
        ).toBeInTheDocument();

I do not notice this taking a long time to load in the app, so these flakiness failures are related to how the app loads with mocks in the test environment.

For now, implement everywhere and just hardcode the timeout to 10000 (in testing I saw some flakiness with 5000). We likely have flakiness with this waitFor approach but we won't figure it out until it starts failing 5% of the time in CI.

Going forward, we "should" have a standardized function for waiting for components to load. We have implemented this in test but it is only implemented (for now) in the OrderBook tests, which are fully migrated to typescript. Need to migrate all the tests to typescript, but that exercise is not related to this diff.

This revision now requires changes to proceed.Tue, May 13, 16:54

remove failed-test file, and remove waitFor from test, add increased timeout value to prevent timeout failures in tests

Failed tests logs:

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

Expected element to have text content:
  0.00 XEC
Received:
  9,513.12 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/Home/__tests__/Home.test.js:81:11)
    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 /> 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:698:11)
    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:748:11)
    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:786:11)
    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:902:11)
    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:1006:11)
    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:1082:11)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)

Each failure log is accessible here:
CashTab Unit Tests: <Home /> Renders the loading component while loading, then the Home screen
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

Failed tests logs:

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

Expected element to have text content:
  0.00 XEC
Received:
  9,513.12 XEC
    at Object.toHaveTextContent (/work/cashtab/src/components/Home/__tests__/Home.test.js:81:11)
    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 /> 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:698:11)
    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:748:11)
    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:786:11)
    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:902:11)
    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:1006:11)
    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:1082:11)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)

Each failure log is accessible here:
CashTab Unit Tests: <Home /> Renders the loading component while loading, then the Home screen
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

Failed tests logs:

====== 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:698:11)
    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:748:11)
    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:786:11)
    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:902:11)
    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:1006:11)
    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:1082:11)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)

Each failure log is accessible here:
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

Failed tests logs:

====== 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:698:11)
    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:748:11)
    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:786:11)
    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:902:11)
    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:1006:11)
    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:1082:11)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)

Each failure log is accessible here:
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

bytesofman added inline comments.
cashtab/src/components/App/__tests__/App.test.js
696–698 ↗(On Diff #53974)

use the same approach everywhere for the "wait to load" -- wait to find the text in the doc, do not wait for the contents of this div to exact match the text

expect(
            await screen.findByText('9,513.12 XEC', {}, { timeout: 10000 }),
        ).toBeInTheDocument();
746 ↗(On Diff #53974)

ditto

784 ↗(On Diff #53974)

ditto

900 ↗(On Diff #53974)

ditto

1004 ↗(On Diff #53974)

ditto

1080 ↗(On Diff #53974)

ditto

cashtab/src/components/App/fixtures/__tests__/CashtabTestWrapper.test.js
94 ↗(On Diff #53974)

ditto

This revision now requires changes to proceed.Tue, May 13, 18:13

findbyText instead of findbyTitle

Failed tests logs:

====== 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:95:11)
    at runNextTicks (node:internal/process/task_queues:60:5)
    at listOnTimeout (node:internal/timers:545:9)
    at processTimers (node:internal/timers:519:7)

Each failure log is accessible here:
CashTab Unit Tests: <CashtabTestWrapper /> With default props, renders App component

This revision is now accepted and ready to land.Tue, May 13, 22:13
This revision was automatically updated to reflect the committed changes.