Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feature: E2E real data #172

Closed
wants to merge 1 commit into from
Closed

feature: E2E real data #172

wants to merge 1 commit into from

Conversation

gbarkhatov
Copy link
Contributor

@gbarkhatov gbarkhatov commented Sep 25, 2024

Added real wallet E2E tests

  1. Wallets are generated via real mnemonic. Both mainnet/signet and taproot/native segwit
  2. Since window.btcwallet is something we need to inject, and we do want our transactions to be real, we have to build our wallets with all the necessary bitcoin libs. Currently, I use webpack for that
  3. The only mocking part is the initial UTXOs and POST requests. I.e. under the hood real BTC signatures are happening
  4. By default, Playwright will use the .env.local that you use. If you want to use a specific mainnet and signet env variables, you need to create .env.mainnet and .env.signet.
  5. You can use whatever wallets you want in your tests, but some of them require the specific ones. For example, in case of balance and address test, we can connect both signet and mainnet wallets and check the stuff. But anything with the signing involved will require specific env variables. You cannot use mainnet env variables with global parameters expecting X mainnet BTC Tip height on signet wallet. Since signet tip height is going to be differentSostaking, unbonding, withdrawaluse a set of mapping and test required network wallets only. That's because in our app we usesrc/app/context/mempool/BtcHeightProvider.tsxwhich will giveXwhile wallet mempool endpoint might giveYdepending on theenv` variables.

Besides reviewing the code I expect you run the instructions in Readme.md:

  • npm i <- install the dependencies
  • npx playwright install <- this is important
  • npm run build:btcwallet <- to build both wallets
  • npm run test:e2e <- for your .env.local or
  • npm run test:e2e:full <- for your .env.mainnet and .env.signet

Added an E2E section in Readme.md

Video: https://youtu.be/jppgJa9L6gM

Closes:

Partly closes, so the PR is not even bigger:

// Reusable function for checking address
async function checkAddress(page: Page, expectedAddress: string) {
const address = await page.getByTestId("address").textContent();
expect(address).toBe(trim(expectedAddress));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it's better to remove expect condition from here and rename this helper function to regular getter. First of all this is more declarative way of writing tests + this function violates the single responsibility principle (it's a getter and expect function at the same time)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should wrap up all these helper functions into fixtures? Is there any example of using helpers in there docs? I think that fixtures is more PlayWright way

@@ -16,27 +16,32 @@
"sort-imports": "eslint --fix .",
"test": "jest",
"test:watch": "jest --watch",
"build:btcwallet:mainnet": "webpack --config webpack.btcWallet.config.js --env NEXT_PUBLIC_NETWORK=mainnet",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks weird. Instead of putting everything into our DApp application we could create a separate repo for test wallet and deploy it to npm. We could create a very simple browser extension for test purposes and inject it as devDependency into our main application.

I like the Tomo way of doing thing, they have created a separate repo even for their (our) wallet providers, what makes much easier to maintain their SDK and Wallet Providers

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, as I mentioned on the call, we now have simple-staking and a lot of stuff to build the wallet for e2e purposes.
Question though is are we ready to extract wallet providers and all of that outside of simple-staking? Is it a good time now or should we do it later?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All this stuff around wallet providers is so confusing for me right now... If we have mobile/injectable provider in our app why just not use it for the test wallet? We can implement this interface in a separate repo and manually inject it into global window object before we run tests

Copy link
Contributor

@totraev totraev Sep 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I'm getting things right here is the list of packages and modules which we need extract to a new repo

import "core-js/web/url";

import * as ecc from "@bitcoin-js/tiny-secp256k1-asmjs";
import * as bip32 from "@scure/bip32";
import * as bip39 from "@scure/bip39";
import * as bitcoin from "bitcoinjs-lib";
import ECPairFactory from "ecpair";

import { getNetworkFees, getTipHeight } from "@/utils/mempool_api";
import { getPublicKeyNoCoord, isTaproot } from "@/utils/wallet";
import {
  Fees,
  InscriptionIdentifier,
  Network,
  UTXO,
  WalletProvider,
} from "@/utils/wallet/wallet_provider";

import { nativeSegwitMainnetUTXOs } from "../mock/mainnet/nativeSegwit/utxos";
import { taprootMainnetUTXOs } from "../mock/mainnet/taproot/utxos";
import { nativeSegwitSignetUTXOs } from "../mock/signet/nativeSegwit/utxos";
import { taprootSignetUTXOs } from "../mock/signet/taproot/utxos";```

Copy link
Contributor Author

@gbarkhatov gbarkhatov Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we have mobile/injectable provider in our app why just not use it for the test wallet

I did not find the solution for the wallet to be "as it is" in typescript code and we are just injecting the stuff into window.btcwallet that works in node.js and Chrome (other browsers) Playwright env. As soon as we are starting to say "bitcoinjs sign this" or "bip39/32 get the private key" or "mempool fetch the data" it will cause problems
The only solution to this issue that I found is to build a JS wallets packages (build) that have everything they need. Then playwright injects it and calls needed methods

@gbarkhatov
Copy link
Contributor Author

Closed in favor of #193

@gbarkhatov gbarkhatov closed this Oct 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
2 participants