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

Peter/test burn setup #458

Merged
merged 20 commits into from
Sep 14, 2022
Merged

Peter/test burn setup #458

merged 20 commits into from
Sep 14, 2022

Conversation

peterslany
Copy link
Contributor

@peterslany peterslany commented Aug 16, 2022

Adding first version of the UI test automation using Jest and React testing library.

Testing approach

In each test, full application is rendered to make components behave in the same way as in the browser. Calls to parachain ( methods of the interbtc-api ) are mocked as discussed in #402. Therefore the tests run without a need to connect to parachain.

There is a first set of tests for Burn page that aims to replace the manual testing of this page. However, not all tests from manual testing can be replicated by testing the UI with mocked api - these should be tested on lib or parachain side.

How to change tests from manual to automated

  1. Find what is being tested for particular module during the release testing.
    Example:

    *Liquidate a vault to ensure that interBTC can be burned by transferring BTC from the Vault's wallet to a random address.

    Then go to the "Burn" tab (should be visible once the vault is liquidated).*

  2. Find what lib calls need to be mocked. To do that, find call in the UI source code of the tested component.
    Example:
    In order to display the burn tab, I needed to simulate state in which system liquidation vault has tokens to be redeemed. So I need to mock function getMaxBurnableTokens to return monetary amount of more than 0. This will make the dApp display the Burn tab which can be accessed and then the Burn form is rendered.

  3. Write a mocking function with name mock[module][functionName] and assign to it jest.fn() with implementation that imitates original function. Place it in respective file in src/test/mocks/@interlay/interbtc-api/parachain folder
    Example: I created mock function mockRedeemGetMaxBurnableTokens that returns monetary amount of 1 BTC

const mockRedeemGetMaxBurnable Tokens= jest.fn((_currency: CurrencyExt) =>
    newMonetaryAmount(DEFAULT_MAX_BURNABLE_TOKENS, WRAPPED_TOKEN)
);
  1. Import this function into src/test/mocks/@interlay/interbtc-api/index.ts and add it to mockInterBtcApi object under it's original name in particular module.
    Example: I added mockRedeemGetMaxBurnableTokens function to this object under redeem.getMaxBurnableTokens property
import { mockRedeemGetMaxBurnableTokens } from "./parachain";
...
const mockInterBtcApi: RecursivePartial<InterBtcApi> = {
    ...
    redeem: {
        getMaxBurnableTokens: mockRedeemGetMaxBurnableTokens,
   }
   ...
};
  1. Create a new test file in the src/test/pages folder for the tested page and write your tests there.
    Example: I created src/test/pages/Burn.test.tsx file and placed my tests into it.
  2. Run tests with yarn test

Change default mock implementation

All mocked api methods are instances of jest.fn function. This allows for checking if the function was called. It also enables to change the default implementation to one that is needed in the test case. To do that, just import default mock and update it accordingly to test's needs.
For example: I wanted to test that burn tab is not visible when there is not liquidated vault, so I called mockImplementationOnce on it with function that returns monetary amount of 0, therefore simulating state with no wrapped assets to be burned.

import { mockRedeemGetMaxBurnable } from '../mocks/@interlay/interbtc-api';
...
  it('should not display burn tab when there is no liquidated vault', async () => {
    mockRedeemGetMaxBurnable.mockImplementationOnce(() => newMonetaryAmount('0', WRAPPED_TOKEN));

    await act(async () => {
      render(<App />, { path: '/bridge?tab=burn' });
    });

    await waitFor(() => {
      expect(screen.queryByText(/Burn/i)).not.toBeInTheDocument();
    });
  });

Troubleshooting errors

window.bridge.[method] is not a function
The mentioned [method] has to be mocked to make the application work & render correctly. To do so, create default mock for this method (step 3 in the guide).

@vercel
Copy link

vercel bot commented Aug 16, 2022

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Updated
interbtc-ui-interlay ✅ Ready (Inspect) Visit Preview Sep 14, 2022 at 10:52AM (UTC)
interbtc-ui-interlay-testnet ✅ Ready (Inspect) Visit Preview Sep 14, 2022 at 10:52AM (UTC)
interbtc-ui-kintsugi ✅ Ready (Inspect) Visit Preview Sep 14, 2022 at 10:52AM (UTC)
interbtc-ui-kintsugi-testnet ✅ Ready (Inspect) Visit Preview Sep 14, 2022 at 10:52AM (UTC)

@github-actions
Copy link

Running Lighthouse audit...

@peterslany peterslany marked this pull request as ready for review September 2, 2022 15:59
@peterslany peterslany changed the title WIP Peter/test burn setup Peter/test burn setup Sep 2, 2022
Copy link
Contributor

@bvotteler bvotteler left a comment

Choose a reason for hiding this comment

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

LGTM

@nud3l
Copy link
Member

nud3l commented Sep 6, 2022

@peterslany once this is merged, please add a description how to add tests to the runbook here: https://www.notion.so/interlay/How-do-I-add-new-automated-tests-to-the-UI-3ce7ceaada5f4f2e9d7be461f4b59cf2

@nud3l
Copy link
Member

nud3l commented Sep 13, 2022

@tomjeatt @peterslany @danielsimao @crypto-engineer @bvotteler anything else we need to merge this?

package.json Outdated Show resolved Hide resolved
src/test/mocks/setup.ts Outdated Show resolved Hide resolved
@tomjeatt
Copy link
Collaborator

@tomjeatt @peterslany @danielsimao @crypto-engineer @bvotteler anything else we need to merge this?

Couple of very small formatting comments, but apart from that I was imagining we'd wait until after the presentation tomorrow in case any change requests/tweaks come up. That said, it's looking really good to me so I'm not expecting any :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants