Page MenuHomePhabricator

[Cashtab] Patch render logic for spinner
ClosedPublic

Authored by bytesofman on Fri, Jan 17, 02:04.

Details

Reviewers
Fabien
Group Reviewers
Restricted Project
Commits
rABC03869debbc95: [Cashtab] Patch render logic for spinner
Summary

Somewhere a long time ago, probably while handling wallet migrations, this spinner functionality was broken.

Patch.

Cashtab uses a Spinner component to lock the UI while wallet data is being written to storage. loading is provided by context, so any screen may arbitrarily set loading to true if it is necessary to lock the UI while some data necessary for user action is loaded. It is mainly used for when we update the wallet's utxo set, though we only briefly lock the UI here while the UTXO set is being written to storage.

One issue with Cashtab now is that wallet changes can be "too fast," and trigger too many write actions and state updates. I have a stack of diffs in now to handle this. However, one thing they need to work is for the loading spinner to actually render when loading is set to true. The logic for this was broken some time ago but this was not noticed as we also have not been using loading from screen's other than the App screen; it has primarily been used for the niche use case of a user migrating to an updated wallet shape.

This diff fixes the loading functionality so that a Spinner is rendered whenever loading is true. This change is simple but the knock-on impact on Cashtab's testing could be complex, because almost every test waits for loading to complete in some way before checking for expected data to be rendered. Different screens load in different times and make use of different limited loading components, so each test must be customized for handling this appropriately.

Ideally, we will have a streamlined and standardized loading approach -- which this top level spinner will support. However will take some time to get here, and patching this issue now is imo the first step.

Test Plan

npm test

The test added in App.test.js is the one that specifically confirms expected behavior of this diff.

Diff Detail

Repository
rABC Bitcoin ABC
Branch
patch-app-spinner
Lint
Lint Passed
Unit
No Test Coverage
Build Status
Buildable 32137
Build 63765: Build Diffcashtab-tests
Build 63764: arc lint + arc unit

Event Timeline

bytesofman edited the test plan for this revision. (Show Details)

Failed tests logs:

====== CashTab Unit Tests: <Token /> For an uncached token with no balance, we show a spinner while loading the token info, then show an info screen and open agora offers ======
TestingLibraryElementError: Found multiple elements with the title: Loading.

Here are the matching elements:

Ignored nodes: comments, script, style
<div
  class="sc-cSHVUG kakYiA"
  title="Loading"
>
  <div />
  <div />
  <div />
  <div />
</div>

Ignored nodes: comments, script, style
<div
  class="sc-cSHVUG kakYiA"
  title="Loading"
>
  <div />
  <div />
  <div />
  <div />
</div>

(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)).

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-AnqlK jzmxJP"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-keFjpB kpRoMq"
      >
        <div
          class="sc-jWojfa dWofVP"
        >
          <div
            class="sc-dTLGrV hVKRQa"
          >
            <img
              alt="cashtab"
              class="sc-ivVeuv evHkvQ"
              src="test-file-stub"
            />
          </div>
          <div
            class="sc-hdPSEv NMixZ"
          >
            <div
              class="sc-bqjOQT bJwGKq"
            >
              <select
                class="sc-jkCMRl gBdLKu"
                data-testid="wallet-select"
                id="wallets"
                name="wallets"
              >
                <option
                  class="sc-crNyjn fdrrlO"
                  value="Transaction Fixtures"
                >
                  Transaction Fixtures
                </option>
              </select>
              <div
                class="sc-lcpuFF iSIgFF"
              >
                <button
                  aria-label="Copy ecash:qqa9lv3kjd8vq7952p7rq0f6lkpqvlu0cydvxtd70g"
                  class="sc-cJSrbW kZNvLw"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <div
                  class="sc-eerKOB cvXwwv"
                >
                  <div
                    class="sc-emmjRN bSWkUh"
                  >
                    <input
                      checked=""
                      class="sc-gFaPwZ iPJMNd"
                      id="show-hide-balance"
                      name="show-hide-balance"
                      title="show-hide-balance"
                      type="checkbox"
                    />
                    <label
                      class="sc-cpmLhU iUeRKn"
                      for="show-hide-balance"
                    >
                      <span
                        class="sc-dymIpo hGwQkt"
                        data-off=""
                        data-on=""
                      />
                      <span
                        class="sc-bnXvFD cpOMDW"
                      />
                    </label>
                  </div>
                </div>
              </div>
            </div>
            <div
              class="sc-cmIlrE dkSzlg"
              title="Wallet Info"
            >
              <div
                class="sc-cpHetk jEKVml"
              >
                <div
                  class="sc-nrwXf bsChRe"
                  title="Balance XEC"
                >
                  9,513.12
                   
                  XEC
                </div>
              </div>
            </div>
          </div>
          <div
            class="sc-chAAoq bzVCQv"
          >
            <div
              class="sc-jKVCRD deirAb"
            >
              <div
                class="sc-kaNhvL ixwxts"
                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-bbmXgH fbVlNd"
                >
                  You do not hold this token.
                </div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="sc-kVrTmx exLrES"
        >
          <div
            class="sc-fHSTwm jBcETl"
          >
            <img
              alt="cashtab"
              class="sc-ivVeuv evHkvQ"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-ekkqgF dcQEnG"
            title="Show Other Screens"
          >
            <span
              class="sc-iBmynh dPVmzy"
            />
            <div
              class="sc-fKGOjr buAdOz"
              title="Other Screens"
            >
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                <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 getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:20:35)
    at getMultipleElementsFoundError (/work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:23:10)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:55:13
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByTitle (/work/cashtab/src/components/Etokens/__tests__/Token.test.js:821:23)
    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 /> For an uncached token with no balance, we show a chronik query error if we are unable to fetch the token info ======
TestingLibraryElementError: Found multiple elements with the title: Loading.

Here are the matching elements:

Ignored nodes: comments, script, style
<div
  class="sc-cSHVUG kakYiA"
  title="Loading"
>
  <div />
  <div />
  <div />
  <div />
</div>

Ignored nodes: comments, script, style
<div
  class="sc-cSHVUG kakYiA"
  title="Loading"
>
  <div />
  <div />
  <div />
  <div />
</div>

(If this is intentional, then use the `*AllBy*` variant of the query (like `queryAllByText`, `getAllByText`, or `findAllByText`)).

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-AnqlK jzmxJP"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-keFjpB kpRoMq"
      >
        <div
          class="sc-jWojfa dWofVP"
        >
          <div
            class="sc-dTLGrV hVKRQa"
          >
            <img
              alt="cashtab"
              class="sc-ivVeuv evHkvQ"
              src="test-file-stub"
            />
          </div>
          <div
            class="sc-hdPSEv NMixZ"
          >
            <div
              class="sc-bqjOQT bJwGKq"
            >
              <select
                class="sc-jkCMRl gBdLKu"
                data-testid="wallet-select"
                id="wallets"
                name="wallets"
              >
                <option
                  class="sc-crNyjn fdrrlO"
                  value="Transaction Fixtures"
                >
                  Transaction Fixtures
                </option>
              </select>
              <div
                class="sc-lcpuFF iSIgFF"
              >
                <button
                  aria-label="Copy ecash:qqa9lv3kjd8vq7952p7rq0f6lkpqvlu0cydvxtd70g"
                  class="sc-cJSrbW kZNvLw"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <div
                  class="sc-eerKOB cvXwwv"
                >
                  <div
                    class="sc-emmjRN bSWkUh"
                  >
                    <input
                      checked=""
                      class="sc-gFaPwZ iPJMNd"
                      id="show-hide-balance"
                      name="show-hide-balance"
                      title="show-hide-balance"
                      type="checkbox"
                    />
                    <label
                      class="sc-cpmLhU iUeRKn"
                      for="show-hide-balance"
                    >
                      <span
                        class="sc-dymIpo hGwQkt"
                        data-off=""
                        data-on=""
                      />
                      <span
                        class="sc-bnXvFD cpOMDW"
                      />
                    </label>
                  </div>
                </div>
              </div>
            </div>
            <div
              class="sc-cmIlrE dkSzlg"
              title="Wallet Info"
            >
              <div
                class="sc-cpHetk jEKVml"
              >
                <div
                  class="sc-nrwXf bsChRe"
                  title="Balance XEC"
                >
                  9,513.12
                   
                  XEC
                </div>
              </div>
            </div>
          </div>
          <div
            class="sc-chAAoq bzVCQv"
          >
            <div
              class="sc-jKVCRD deirAb"
            >
              <div
                class="sc-kaNhvL ixwxts"
                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-bbmXgH fbVlNd"
                >
                  You do not hold this token.
                </div>
              </div>
            </div>
          </div>
        </div>
        <div
          class="sc-kVrTmx exLrES"
        >
          <div
            class="sc-fHSTwm jBcETl"
          >
            <img
              alt="cashtab"
              class="sc-ivVeuv evHkvQ"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-ekkqgF dcQEnG"
            title="Show Other Screens"
          >
            <span
              class="sc-iBmynh dPVmzy"
            />
            <div
              class="sc-fKGOjr buAdOz"
              title="Other Screens"
            >
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                <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 getElementError (/work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:20:35)
    at getMultipleElementsFoundError (/work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:23:10)
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:55:13
    at /work/cashtab/node_modules/@testing-library/dom/dist/query-helpers.js:95:19
    at Object.getByTitle (/work/cashtab/src/components/Etokens/__tests__/Token.test.js:867:23)
====== CashTab Unit Tests: <Token /> For an invalid tokenId, we do not query chronik, and we show an invalid tokenId notice ======
Error: expect(element).not.toBeInTheDocument()

expected document not to contain element, found <div class="sc-cSHVUG kakYiA" title="Loading"><div /><div /><div /><div /></div> instead
    at Object.toBeInTheDocument (/work/cashtab/src/components/Etokens/__tests__/Token.test.js:903:52)

Each failure log is accessible here:
CashTab Unit Tests: <Token /> For an uncached token with no balance, we show a spinner while loading the token info, then show an info screen and open agora offers
CashTab Unit Tests: <Token /> For an uncached token with no balance, we show a chronik query error if we are unable to fetch the token info
CashTab Unit Tests: <Token /> For an invalid tokenId, we do not query chronik, and we show an invalid tokenId notice

Tail of the build log:

Run `npm audit` for details.

> ecash-lib@1.3.0 build
> tsc && tsc -p ./tsconfig.build.json && cp -r ./src/ffi ./dist

/work/modules/ecash-agora /work/abc-ci-builds/cashtab-tests

added 364 packages, and audited 367 packages in 1s

60 packages are looking for funding
  run `npm fund` for details

2 vulnerabilities (1 moderate, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

> ecash-agora@0.3.1 build
> tsc && tsc -p ./tsconfig.build.json

/work/cashtab /work/abc-ci-builds/cashtab-tests
npm warn deprecated @humanwhocodes/config-array@0.11.14: Use @eslint/config-array instead
npm warn deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm warn deprecated eslint@8.56.0: This version is no longer supported. Please see https://eslint.org/version-support for other options.

added 1494 packages, and audited 3315 packages in 23s

320 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (6 moderate, 2 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> cashtab@3.12.2 build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

TS2339: Property 'setCashtabState' does not exist on type 'UseWalletReturnType'.
    86 |     const {
    87 |         cashtabState,
  > 88 |         setCashtabState,
       |         ^^^^^^^^^^^^^^^
    89 |         updateCashtabState,
    90 |         fiatPrice,
    91 |         loading,


Build cashtab-tests failed with exit code 1

back out unrelated changes, update tests

Tail of the build log:

Run `npm audit` for details.

> ecash-lib@1.3.0 build
> tsc && tsc -p ./tsconfig.build.json && cp -r ./src/ffi ./dist

/work/modules/ecash-agora /work/abc-ci-builds/cashtab-tests

added 364 packages, and audited 367 packages in 2s

60 packages are looking for funding
  run `npm fund` for details

2 vulnerabilities (1 moderate, 1 high)

To address all issues, run:
  npm audit fix

Run `npm audit` for details.

> ecash-agora@0.3.1 build
> tsc && tsc -p ./tsconfig.build.json

/work/cashtab /work/abc-ci-builds/cashtab-tests
npm warn deprecated @humanwhocodes/config-array@0.11.14: Use @eslint/config-array instead
npm warn deprecated @humanwhocodes/object-schema@2.0.3: Use @eslint/object-schema instead
npm warn deprecated eslint@8.56.0: This version is no longer supported. Please see https://eslint.org/version-support for other options.

added 1494 packages, and audited 3315 packages in 25s

320 packages are looking for funding
  run `npm fund` for details

8 vulnerabilities (6 moderate, 2 high)

To address issues that do not require attention, run:
  npm audit fix

To address all issues (including breaking changes), run:
  npm audit fix --force

Run `npm audit` for details.

> cashtab@3.12.2 build
> node scripts/build.js

Creating an optimized production build...
Failed to compile.

TS2322: Type '{ wallets: CashtabWallet[]; settings: CashtabSettings; updateCashtabState: (key: string, value: CashtabCache | CashtabWallet[] | ... 4 more ... | StoredCashtabWallet[]) => Promise<...>; loading: boolean; }' is not assignable to type 'IntrinsicAttributes & Pick<{ wallets: any; settings: any; updateCashtabState: any; }, never> & Pick<InferProps<{ wallets: Requireable<(InferProps<{ mnemonic: Requireable<string>; name: Requireable<...>; paths: Requireable<...>; state: Requireable<...>; }> | null | undefined)[]>; settings: Requireable<...>; updateCas...'.
  Property 'loading' does not exist on type 'IntrinsicAttributes & Pick<{ wallets: any; settings: any; updateCashtabState: any; }, never> & Pick<InferProps<{ wallets: Requireable<(InferProps<{ mnemonic: Requireable<string>; name: Requireable<...>; paths: Requireable<...>; state: Requireable<...>; }> | null | undefined)[]>; settings: Requireable<...>; updateCas...'.
    186 |                                                     updateCashtabState
    187 |                                                 }
  > 188 |                                                 loading={loading}
        |                                                 ^^^^^^^
    189 |                                             />
    190 |                                             <BalanceHeaderContainer title="Wallet Info">
    191 |                                                 <BalanceHeader


Build cashtab-tests failed with exit code 1

back out unrelated line break

Failed tests logs:

====== CashTab Unit Tests: <Agora /> Screen loads as expected if there are no agora partial listings ======
TestingLibraryElementError: Unable to find an element with the text: No whitelisted tokens are currently listed for sale. Try loading all offers.. 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-AnqlK jzmxJP"
    >
      <section
        aria-atomic="false"
        aria-label="Notifications Alt+T"
        aria-live="polite"
        aria-relevant="additions text"
        class="Toastify"
      />
      <div
        class="sc-keFjpB kpRoMq"
      >
        <div
          class="sc-jWojfa dWofVP"
        >
          <div
            class="sc-dTLGrV hVKRQa"
          >
            <img
              alt="cashtab"
              class="sc-ivVeuv evHkvQ"
              src="test-file-stub"
            />
          </div>
          <div
            class="sc-hdPSEv NMixZ"
          >
            <div
              class="sc-bqjOQT bJwGKq"
            >
              <select
                class="sc-jkCMRl fVHViG"
                data-testid="wallet-select"
                id="wallets"
                name="wallets"
              >
                <option
                  class="sc-crNyjn fdrrlO"
                  value="Agora Partial Alpha"
                >
                  Agora Partial Alpha
                </option>
                <option
                  class="sc-crNyjn fdrrlO"
                  value="Agora Partial Beta"
                >
                  Agora Partial Beta
                </option>
              </select>
              <div
                class="sc-lcpuFF iSIgFF"
              >
                <button
                  aria-label="Copy ecash:qqpmsv8yh8wwx3lnf92rrc0e6yq97j6zqs8av8vx8h"
                  class="sc-cJSrbW kZNvLw"
                >
                  <svg
                    title="copy-paste"
                  />
                </button>
                <div
                  class="sc-eerKOB cvXwwv"
                >
                  <div
                    class="sc-emmjRN bSWkUh"
                  >
                    <input
                      checked=""
                      class="sc-gFaPwZ iPJMNd"
                      id="show-hide-balance"
                      name="show-hide-balance"
                      title="show-hide-balance"
                      type="checkbox"
                    />
                    <label
                      class="sc-cpmLhU iUeRKn"
                      for="show-hide-balance"
                    >
                      <span
                        class="sc-dymIpo hGwQkt"
                        data-off=""
                        data-on=""
                      />
                      <span
                        class="sc-bnXvFD cpOMDW"
                      />
                    </label>
                  </div>
                </div>
              </div>
            </div>
            <div
              class="sc-cmIlrE dkSzlg"
              title="Wallet Info"
            >
              <div
                class="sc-cpHetk jEKVml"
              >
                <div
                  class="sc-nrwXf bsChRe"
                  title="Balance XEC"
                >
                  4,200.00
                   
                  XEC
                </div>
              </div>
              <div
                class="sc-eitiEO lmPAIm"
                title="Balance in Local Currency"
              >
                $
                0.13
                 
                USD
              </div>
              <p
                class="sc-bhlBdH umymk"
                title="Price in Local Currency"
              >
                1 
                XEC
                 = 
                0.00003000
                 
                USD
              </p>
            </div>
          </div>
          <div
            class="sc-chAAoq bzVCQv"
          >
            <div
              class="sc-yZwTr birQAH"
            >
              <h2>
                Token Offers
              </h2>
              <div>
                Sort by:
                <div
                  class="sc-hwcHae jnZGJM"
                  title="Sort by TokenId"
                >
                  TokenID
                </div>
                <div
                  class="sc-hwcHae dfnqEL"
                  disabled=""
                  title="Sort by Offer Count"
                >
                  Offers
                  <div>
                    <div
                      class="sc-jzJRlG eQTBdJ"
                      title="Loading OrderBook info..."
                    >
                      <div />
                      <div />
                      <div />
                      <div />
                    </div>
                  </div>
                </div>
                <span
                  class="sc-fjhmcy ceHQEJ"
                  title="Toggle Active Offers"
                >
                  My Listings
                </span>
              </div>
            </div>
            <div
              class="sc-gacfCG gpjPEu"
              title="Active Offers"
            >
              <div
                class="sc-cqPOvA jDuRbt"
              >
                <div
                  class="sc-eKZiaR cOnhGl"
                >
                  <div
                    class="sc-jzJRlG eQTBdJ"
                    title="Loading"
                  >
                    <div />
                    <div />
                    <div />
                    <div />
                  </div>
                </div>
                <div
                  class="sc-eKZiaR cOnhGl"
                >
                  <div
                    class="sc-jzJRlG eQTBdJ"
                    title="Loading"
                  >
                    <div />
                    <div />
                    <div />
                    <div />
                  </div>
                </div>
              </div>
            </div>
            <button
              class="sc-caSCKo sc-kjoXOD DHATx"
              style="margin-top: 12px;"
            >
              Load all offers
            </button>
          </div>
        </div>
        <div
          class="sc-kVrTmx exLrES"
        >
          <div
            class="sc-fHSTwm jBcETl"
          >
            <img
              alt="cashtab"
              class="sc-ivVeuv evHkvQ"
              src="test-file-stub"
            />
          </div>
          <button
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Transactions
            </span>
            <svg />
          </button>
          <button
            aria-label="Send Screen"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Send
            </span>
            <svg
              title="tx-sent"
            />
          </button>
          <button
            aria-label="Tokens"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Tokens
            </span>
            <svg
              title="Tokens"
            />
          </button>
          <button
            aria-label="Receive"
            class="sc-jvEmr hqZIZM"
          >
            <span>
              Receive
            </span>
            <svg
              title="tx-received"
            />
          </button>
          <div
            class="sc-ekkqgF dcQEnG"
            title="Show Other Screens"
          >
            <span
              class="sc-iBmynh dPVmzy"
            />
            <div
              class="sc-fKGOjr buAdOz"
              title="Other Screens"
            >
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Wallet Backup
                </p>
                <svg
                  title="wallet"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Wallets
                </p>
                <svg
                  title="wallets"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Listed NFTs
                </p>
                <svg
                  title="NFT"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Agora
                </p>
                <svg
                  title="Meme Agora"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Contacts
                </p>
                <svg
                  title="Contact List"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Airdrop
                </p>
                <svg
                  title="tx-airdrop"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                 
                <p>
                  Rewards
                </p>
                <svg
                  title="Cashtab Rewards"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                <p>
                  Sign & Verify
                </p>
                <svg
                  class="sc-htpNat bPFBeM"
                />
              </button>
              <button
                class="sc-hycgNl bNyILw"
              >
                <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.getByText (/work/cashtab/src/components/Agora/__tests__/index.test.js:143:20)
    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: <Agora /> Screen loads as expected if there are no agora partial listings

update test for loading flakiness

Failed tests logs:

====== CashTab Unit Tests: <Token /> Renders the burn token success notification upon successful burn tx broadcast ======
Error: expect(received).toHaveProperty(path, value)

Expected path: "checked"

Expected value: true
Received value: false
    at Object.toHaveProperty (/work/cashtab/src/components/Etokens/__tests__/Token.test.js:446:56)

Each failure log is accessible here:
CashTab Unit Tests: <Token /> Renders the burn token success notification upon successful burn tx broadcast

this patch will probably cause a number of tests to be flaky. Will fix them as I find them. Hard to do a one-time pass and clean them all up now since it's not obvious which ones will have the loading spinner.

Will be gradually cleaned up, along with the gradual migration of all tests and mocks to typescript.

I assume the flakiness of the test you're referring to is when the int test is waiting for the spinner to disappear but it doesn't, and the await waitFor() call just hangs there holding up the entire test suite?

// Wait for Cashtab wallet info to load
await waitFor(() =>
    expect(screen.queryByTitle('Loading...')).not.toBeInTheDocument(),
);
Fabien requested changes to this revision.Fri, Jan 17, 08:20
Fabien added a subscriber: Fabien.

So before this patch it's broken and after this patch it's not, great.
May I ask how it's broken and how it's fixed ? Because I can't spot the change in behavior.

This revision now requires changes to proceed.Fri, Jan 17, 08:20

So before this patch it's broken and after this patch it's not, great.
May I ask how it's broken and how it's fixed ? Because I can't spot the change in behavior.

Yes, some history changed before I got this diff to have tests passing. When I first pushed it up, the only test that changed was the App test.

Before this diff

  • Cashtab intended behavior is for a spinner to lock the UI when loading is true. This happens on the App component, which renders the routes, so it will work on any given screen.
  • However the conditional rendering has a bug, such that even when loading is true, the Spinner may not render. This diff patches the bug.
  • For the test in App -- we show that this spinner is in the screen when the component loads, which is expected behavior.

However, there are a number of knock ons from this change. Cashtab has many tests that need to wait for stuff to load. Thish stuff takes longer depending on the screen. Some of the tests are configured to wait for inline spinners to go away, others are configured to wait for cashtab's bootup to complete. Now that the wallet update spinner is fixed, there is something else that some tests may need to wait for. So, this has caused some other tests to fail. Running the CI and locally revealed some tests to be flaky, i.e. it can be difficult to tell which loading component we must wait for, and I have not (yet) managed to come up with a "catch all" routine to just wait for everything to load in a way that is standard for all tests.

At the moment, I don't think I can confidently predict exactly how to fix all of the various tests and their loading conditions to wait for the right spinners to be present or not present. So we may see some test flakiness after this diff (we had test flakiness of the same kind before this diff, it's just that I iterated through it on those tests with this bug in the system; now that the bug is gone there may be some new loading conditions to handle in existing tests).

This bug was discovered while fixing the wallet changing behavior when I noticed that the spinnner was not appearing even when I manually setLoading(true) to wait for a wallet to load.

I assume the flakiness of the test you're referring to is when the int test is waiting for the spinner to disappear but it doesn't, and the await waitFor() call just hangs there holding up the entire test suite?

// Wait for Cashtab wallet info to load
await waitFor(() =>
    expect(screen.queryByTitle('Loading...')).not.toBeInTheDocument(),
);

Flakiness in this case means that some tests pass some or most of the time, but could fail due to a given load condition not taking a constant amount of time. It's an existing issue in Cashtab that needs a proper standardized solution. Complexity because Cashtab has lots of different data, basically all of it async. This has gotten much better through typescript, cleaner loading routines in useWallet.ts, and an improved understanding of react test library. But there is still room for improvement.

Since so many tests in Cashtab wait for data to load, and the App screen spinner can lock the UI on any screen --- patching this kind of bug (which prevented a loading spinner from rendering) has test impact beyond just the App screen.

So before this patch it's broken and after this patch it's not, great.
May I ask how it's broken and how it's fixed ? Because I can't spot the change in behavior.

Yes, some history changed before I got this diff to have tests passing. When I first pushed it up, the only test that changed was the App test.

Before this diff

  • Cashtab intended behavior is for a spinner to lock the UI when loading is true. This happens on the App component, which renders the routes, so it will work on any given screen.
  • However the conditional rendering has a bug, such that even when loading is true, the Spinner may not render. This diff patches the bug.
  • For the test in App -- we show that this spinner is in the screen when the component loads, which is expected behavior.

However, there are a number of knock ons from this change. Cashtab has many tests that need to wait for stuff to load. Thish stuff takes longer depending on the screen. Some of the tests are configured to wait for inline spinners to go away, others are configured to wait for cashtab's bootup to complete. Now that the wallet update spinner is fixed, there is something else that some tests may need to wait for. So, this has caused some other tests to fail. Running the CI and locally revealed some tests to be flaky, i.e. it can be difficult to tell which loading component we must wait for, and I have not (yet) managed to come up with a "catch all" routine to just wait for everything to load in a way that is standard for all tests.

At the moment, I don't think I can confidently predict exactly how to fix all of the various tests and their loading conditions to wait for the right spinners to be present or not present. So we may see some test flakiness after this diff (we had test flakiness of the same kind before this diff, it's just that I iterated through it on those tests with this bug in the system; now that the bug is gone there may be some new loading conditions to handle in existing tests).

This bug was discovered while fixing the wallet changing behavior when I noticed that the spinnner was not appearing even when I manually setLoading(true) to wait for a wallet to load.

The rationale should be in the diff summary

This revision is now accepted and ready to land.Fri, Jan 17, 21:29
This revision was automatically updated to reflect the committed changes.